Kaede Akatsuki

中二病也要开发 Android

Bash 编程 - 从入门到入土

Bash,面向 Google 编程!

Bash,一门典型的面向 Google 编程的语言(类似的还有面向 StackOverflow 编程的 vim),最大的语言特性是其 “不确定性原理”(你要么学会了 Bash 了语法,要么写出了能正常运行的 Bash 脚本,但是不能即学会了语法又写出了脚本),你今天刚学会的语法,到了明天就不一定会记得了;今天刚写好的代码,到了明天就不一定能运行了。与其回忆昨天学了什么,还不如直接问 Google。

Bash 学习的深入可真是 “从入门到入土”,个人感觉最佳实践应该是把 Bash 作为脚本入口,包一层别的脚本语言(比如 Python),后续工作全交由后者处理。

阅读全文

增量静态检查(SPA)在代码合入检查里的应用

静态程序分析,是指在不运行程序的情况下分析检查代码里存在的问题。这项技术在代码质量、漏洞扫描等领域有广泛的使用。常见分析工具包括 CheckStyle、Lint、FindBugs 等,也有商用的 Coverity。本文主要讲述为我们在 Android 项目 Merge Request 合入检查里对静态程序分析技术的应用,核心内容是增量代码的静态分析方案,至于各种检查工具的对比筛选,请参考文末提供的 References。

阅读全文

一种 Android 应用内全局获取 Context 实例的装置

哥白尼・罗斯福・马丁路德・李开复・嫁衣曾经说过

Where there is an Android App, there is an Application context.

没毛病,扎心了。App 运行的时候,肯定是存在至少一个 Application 实例的。同时,Context 我们再熟悉不过了,写代码的时候经常需要使用到 Context 实例,它一般是通过构造方法传递进来,通过方法的形式参数传递进来,或者是通过 attach 方法传递进我们需要用到的类。Context 实在是太重要了,以至于我经常恨不得着藏着掖着,随身带着,这样需要用到的时候就能立刻掏出来用用。但是换个角度想想,既然 App 运行的时候,Application 实例总是存在的,那么为何不设置一个全局可以访问的静态方法用于获取 Context 实例,这样以来就不需要上面那些繁琐的传递方式。

说到这里,有的人可能说想这不是我们经常干的好事吗,有必要说的这么玄乎?少侠莫急,请听吾辈徐徐道来。

阅读全文

西方程序员跑得比谁都快

昨天刚刚发表了一篇文章(ProGuard 又搞了个大新闻),主要吐槽的是项目里面使用 ProGuard 工具导致的一个诡异的坑。其中根本的原因就是,ProGuard 混淆 Java 注解类的时候,把两个方法混淆成同样的名字,导致 dx 工具在打包 .dex 文件的时候报错。

本来以为这件事情算是告一段落了,没想到自己还是太 Naive 了。今天早上突然收到了 ProGuard 开发者发来的一份邮件,Exciting!邮件里谈到了这次的坑出现的真正原因 —— Java 源码和字节码(bytecode)里方法的重载(OverLoading)。

阅读全文

ProGuard 又搞了个大新闻

一般情况下,Android 项目经常开启 ProGuard 功能来混淆代码,一方面可以降低应用被反编译后代码的友善度,增加被逆向的难度,另一方面开可以通过精简 Java API 的名字来减少代码的总量,从而精简应用编译后的体积。

ProGuard 有个比较坑爹的问题。在开发阶段,我们一般不启用 ProGuard,只有在构建 Release 包的时候才开启。因此,如果有一些 API 被混淆了会出现 BUG,那么在开发阶段我们往往无法察觉 BUG,只有在构建发布包的时候才发现,甚至要等发布到线上了才能发现,这种时候解决问题的成本就很大了。
不过今天被 ProGuard 坑的不是混淆 API 导致的 BUG,这货在之前相当长的一段时间里一直相安无事,最近突然又搞了个大新闻,而且问题排查起来相当蹊跷、诡异。

阅读全文

IDEA 注释优化插件:Comment Formatter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//               +---------------------------------------------+
// | public static final FiledA mFiledA; // xxx |
// | private static final FiledB mFiledB; // xxx |
// | public FiledC mFiledC; // xxx |
// | protected final FiledD mFiledD; // xxx |
// | FiledE mFiledE; // xxx |
// | | |
// | v |
// | public static final FiledA mFiledA; // xxx |
// | private static final FiledB mFiledB; // xxx |
// | public FiledC mFiledC; // xxx |
// | protected final FiledD mFiledD; // xxx |
// | FiledE mFiledE; // xxx |
// +---------------------------------------------+

Comment Formatter is an IntelliJ IDEA plugin (also works in Android Studio) that formats comments as above. It will force all the comments to align to the longest one.

Getting Started

  1. Install CommentFormatter from release or IntelliJ Plugin Repository.
  2. Select all the lines which you wanna format.
  3. Select Tool - Format comment or toggle Ctrl + Cmd + L to format.

Check it out.

通过预安装给 MultiDex 加速

在 Android Kikat 及以前的 Android 系统上,构建或安装 Apk 会出现 “65535 方法数超标 ” 以及 “INSTALL_FAILED_DEXOPT” 问题,MultiDex 是 Google 为了解决这个问题问题而开发的一个 Support 库。MultiDex 出现的具体背景、使用方式可以参考 给 App 启用 MultiDex 功能,而 MultiDex Support 库的工作机制、源码分析可以参考 MultiDex 工作原理分析和优化方案

MultiDex 的使用虽然很简单便捷,但是有个比较蛋疼的问题,就是在 App 第一次冷启动的时候会产生明显的卡顿现象。经过测试和统计,根据 Apk 包的大小、Android 系统版本的不同,这个卡顿时间一般是 2000 到 5000 毫秒左右,极端的情况下甚至可以到 20000 + 毫秒。通过之前的分析,我们知道具体的卡顿产生在 MultiDex 解压、优化 dex 这两个过程,而且只在第一次冷启动的时候才会触发这两个过程。那么优化的方式也很简单,在安装 Apk 前先对新版本的 Apk 做好解压和优化工作,就能在安装后第一次冷启动的时候避开这两个耗时的过程了。

阅读全文

MultiDex 工作原理分析和优化方案

动态加载技术(插件化)系列已经坑了有一段时间了,不过 UP 主我并没有放弃治疗哈,相信在不就的未来就可以看到 “系统 Api Hook 模式” 和插件化框架 Frontia 的更新了。今天要讲的是动态加载技术的亲戚 —— MultiDex。他们的核心原理之一都是 dex 文件的加载。

MultiDex 是 Google 为了解决 “65535 方法数超标 ” 以及 “INSTALL_FAILED_DEXOPT” 问题而开发的一个 Support 库,具体如何使用 MultiDex 现在市面已经有一大堆教程(可以参考 给 App 启用 MultiDex 功能),这里不再赘述。这篇日志主要是配合源码分析 MultiDex 的工作原理,以及提供一些 MultiDex 优化的方案。

阅读全文

Android Logging 的正确姿势

LOG 是任何一种编程语言的第一个 API,通常被初学者用来打印 Hello, World!。
有研究显示,不使用 LOG 或者使用姿势错误的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。
毕竟爱情需要书写,不能是一整张白纸。

LogCat 是 Android 开发者们最熟悉不过的日志打印工具,几乎每一个 Android 项目里面都包含着大量的 Log 相关代码。不过,或许是因为 Log 实在是太过于普通,所以许多人在使用它的时候就显得非常随意,这些错误的使用姿势却会在不经意间给我们带来不少的大坑。

阅读全文

12346