6

Android 5.0 进程A和APK B依赖关系问题的研究

 3 years ago
source link: https://blog.csdn.net/Innost/article/details/43899041
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android 5.0 进程A和APK B依赖关系问题的研究

original.png
阿拉神农 2015-02-21 20:23:38 7876
分类专栏: Android开发系列

(本文来自于和博客上一个朋友的聊天,但可惜我回复后一直没收到这位朋友的回答。故在此把这个问题和大家介绍下,希望能抛砖引玉)

这位朋友的问题是这样的:

应用程序A运行时跑在进程A中,它可以在运行时通过ClassLoader加载另外一个应用程序B。
当然,应用程序B也是可以运行的,它运行在进程B中。
在Android 5.0以前,进程B和进程A是没有关系。但是5.0以后,如果进程B被stop的话,进程A一样会被干掉。
这就是Android 5.0带来的进程A/B依赖关系。
这个问题有几个关键技术点:
1 进程A如何加载应用程序B。这是通过ClassLoader来完成的,主要代码如下所示
  (来自这位朋友的提示:)
在load的时候:
1 在Android 5.0以前,进 程A和应用程序B的关系:没有显示的关系。就是普通的加载
2 在Android 5.0及以后,进程A和应用程序B的关系:显示的绑定。代码在LoadedApk.java中
-->每一个被加载的Apk都对应一个LoaderApk对象。代码在LoadedApk.java中
public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo, 
 CompatibilityInfo compatInfo, ClassLoader baseLoader,  
 boolean securityViolation, boolean includeCode, boolean registerPackage) { 
 final int myUid = Process.myUid(); 
 aInfo = adjustNativeLibraryPaths(aInfo); 
......
 mRegisterPackage = registerPackage; // 在这里被“绑定”了
 mDisplayAdjustments.setCompatibilityInfo(compatInfo); 
}

Android 5.0之后为什么会这样呢?进程A和APK B这种依赖关系有什么用呢?

原来,Android 5.0之后:

1 当进程A加载一个package的时候,framework将调用ActivityManagerService的addPackageDependency 

   这个函数将把进程A和APK B(也就是Package B)绑定到一起去

    这个函数在哪里调用的呢?也在LoadedApk.java中:

2 进程B(也就是Package B本身运行时所在的进程)被杀时,有依赖关系的进程A也会被干掉。这里有几个注意点:

   2.1 如果进程B是自己crash或者被shell kill掉,那么依赖关系不会影响进程A

   2.2 如果进程B是被调用killBackgroundProcess或者forceStopPackage的话,由于ActivityManagerService真正调用的是killPackageProcessesLocked 

        那么依赖关系会导致A被干掉。 从设计角度来看,这本身也是对的,因为APK B运行在自己的进程B,同时也被加载到进程A去运行。

        kill package B的时候就应该stop进程B和A。

        当然,由于5.0之前google没有考虑这么细,所以没有处理这个问题。

   当然,这种依赖关系的引入还有一个原因是Android 5.0在应用程序安装方面的一些新的特性:

1 以前的apk文件 side load到/daa/app等监控目录下不会导致PacakgeManagerService去安装它们。而是需要等到下次重启扫描后,系统才会扫描并安装它们

2 adb install安装的APK,在/data/app目录下会创建一个Package-name(比如com.google.xxx)的文件夹,而apk文件被放到这个package-name目录下,改名叫base.apk

    这么搞的目的是因为:Android终于支持一个进程可以加载多个APK了(当然以前也可以,但现在安装的时候,base-apk是主要逻辑,以后升级了,或者添加新的功能,就不需要重新安装新的base,而是安装一个额外的新apk,这个新apk会被加载到base的那个进程里。)这个功能在SDK文档中已经有展示,但是内容不是很详细

   总之,base apk和新apk需要package名, 签名都一致才可以。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK