最近看了几篇关于flutter使用tinker的博文,说的语焉不详,甚至只是从代码上分析,至于能不能用tinker进行flutter热更新,是没有定论的。所以干脆自己做一个实验来验证一下。
声明,tinker主要是为了android热更新的。
这个tinker是比较两个apk,将差分数据得出另一个apk包,开发者将这个差分apk包用各种手段下发到手机后,手机端的tinker lib会将这个差分apk和原始apk进行合并。重新启动app后,将会加载合并后的dex和so库。安装和打包tinker请参看腾讯的文档。
而flutter所有的dart代码会打进一个叫libapp.so的库中。经试验tinker会发现dart代码的变化并将差分的libapp.so打进patch apk中。
下发patch后,调用tinker的
TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), patchLocalFile);
进行patch的合并,合并后会在data目录下生成一个patch目录,里面存放合并好的dex文件、so文件等。
同时,在Tinker的ApplicationLike::onBaseContextAttached的最后一行设置一下新的libapp.so的patch路径,然后flutter重启后就会自动从patch的文件夹下load这个so了。
TinkerLoadLibrary.installNavitveLibraryABI(getApplication(), "arm64-v8a");
以上这行代码是关键。它把patch的so路径加在了nativelibrarypath的最前面。
所以根本不用分析flutter自己加载so的过程,也不用改写flutter load so 的过程 ,虽然flutter是用c load so的,而不是用System.loadlibrary , 但是flutter自己写的c库也是从系统的nativelibrary里面load ,所以上面那行代码就足够。