以jar/aar直接参与编译的模块,不会做任何检查而直接打包.
这包括也不会检查其发起的引用是否存在 -- 通常你写源码,一个类/函数什么的找不到, IDE是有明显提示的.
jar/aar 与最终apk的目标sdk版本是可以不同的(jar无sdk版本概念,aar有,但是aar<=apk的即可, 若高于也能强行使之编译过)
综上, aar/jar参与编译, 到最终APK可能引入使用不存在API的情况 -- 这在你都是源码编译的时候一般不存在(使用注解强行忽略的扫操作除外) -- 因为IDE会提示, 编译也会报错.
以上一些基本打包的背景知识交代.
若看的不太明白的话, 需要自行补习下apk打包流程的知识.
我知道任意一个第三方sdk调用了某个API. 比如Context.checkPermission(String,int,int):
我现在如何知道这个API的整个安卓SDK更新链路里面的变化情况, 如何做呢?
先上结果 -- 它从sdk-7到sdk-30 都完全没有变化:
ps: 以上涉及一点smali的基本语法, 才能将其映射为java代码.
如何得到这个结果的? 少废话, 上shell命令:
# 1> 找到sdk的路径, 比如我的在~/Android/Sdk, 在sdk路下搜'android.jar'
# 2> 批量反编译(jar-->dex-->smali)
$ find -name 'android.jar' | xargs -I xxx sh -c "echo xxx; /home/moasm/Android/Sdk/build\-tools/28.0.3/dx \-\-dex \-\-core\-library \-\-output xxx.dex xxx"
$ find -name '*.dex' -type f | xargs -I xxx sh -c "d2j\-dex2smali.sh \-f \-o xxx.smalis xxx"
# 注:
# $ type d2j\-dex2smali.sh
# d2j-dex2smali.sh is hashed (/home/moasm/tools/dex2jar-2.0/d2j-dex2smali.sh)
# 3> 查找Context.smali,并找到其checkPermission()函数声明,格式化后输出:
$ find -name 'Context.smali' | sort -t'-' -k2n | xargs grep checkPermission | column -s ':' -t
以上命令运行效果:
答疑:
问1.为什么是android.jar?
答: 编译的时候, 它代表安卓系统参与编译, 你的IDE和编译器如何检出你调用的API合不合理?存不存在的, 都是基于此.
问2. 为什么把jar反编译成smali而不是java?
答: smali其实更适合形式化分析,或者叫正则匹配做一些数据调查/统计什么的.
whats more:
使用一点基本的python数据分析, 基于以上信息现在你可以分析安卓API的各种演化数据了. 比如增加了多少,减少了多少等等