4.1 比较差异
这里的比较差异包含两个部分:比较miui和原生android的差异,比较i9100和原生android的差异。
以framework.jar为例,首先可以建3个目录反汇编这3个jar包:
apktool d framework.jar
执行完毕后,会产生framework.jar.out目录。
接下来使用附件中的脚本rmline.sh运行如下命令:
./rmline.sh framework.jar.out
rmline.sh是用以把smali所有以.line开头的行去掉,这样我们容易比较smali代码上的差别。但是对于所移植的机型,请先复制一份为去掉.line的framework.jar.out版本,因为这些对调试很重要,我们能通过adb logcat报告的错误信息中去定位在哪一行。
接下来用大家说熟悉的文件比较工具来比较差异,Linux下推荐meld, Windows下推荐Beyond Compare。
用meld比较miui和原生android的区别,大家可以看到有很多新增的Miui开头的类,和一个新增的miui目录,这些新增的文件和目录我们直接拷到i9100的framework.jar.out中对应的目录中即可(使用有.line的版本)。为什么我们不把这些新增的类组织在一个单独的jar包中呢(请大家思考一下这个问题)。
不比较那些相同的和新加的,我们只比较修改过的文件,在附件中有一个change-list文件,其中列出了我们修改过的文件,你会发现和这个比较结果有一点不符,如果你比较那些文件,会发现只是一些微小的差异(比如说nop这种空指令),这是由于apktool反编译导致的。我们无需关心,我们只需要比较那些我们修改过的文件。
下面我们就开始修改smali文件了,我将这些修改分成3种情况,选择有代表性的3个文件加以介绍,这3种情况难度依次增加。
4.2 直接替换
以ActivityThread.smali为例,比较发现miui改了其中一个方法getTopLevelResources,而i9100和原生android的实现完全一样,这种情形是最简单也是最happy的,我们改的地方要适配的机型原厂ROM完全没有修改,直接替换就可以了。
4.3 线性代码
还是以ActivityThread.smali为例,对于这个文件,miui一共改了两个方法,一个是上面介绍的,另一个是applyConfigurationToResourcesLocked。通过比较得知,miui修改了这个方法,i9100也修改了这个方法。怎么办呢,我们先分析一下miui修改的代码:
.method final applyConfigurationToResourcesLocked(Landroid/content/res/Configuration;)Z
invoke-virtual {v5, p1}, Landroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I
move-result v0
.local v0, changes:I
invoke-static {v0}, Landroid/app/MiuiThemeHelper;->handleExtraConfigurationChanges(I)V
invoke-virtua