美文网首页
Android应用启动的实质(二)

Android应用启动的实质(二)

作者: 榕城歌者 | 来源:发表于2019-06-23 11:32 被阅读0次

    在上一篇文章中,讲到Zygote的Java框架层中mian(),会创建一个Server端的Socket,这个Socket用来等待AMS来请求Zygote来创建新的应用程序进程。要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经被启动。AMS在启动应用程序时会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote进程将需要的应用程序进程启动。

    ActivityManagerService相关的概念

    ActivityManagerService:简称AMS,服务端对象也是客户端对象(Binder机制决定了角色,对于Zygote它是客户端对象,对于ActivityManagerProxy是服务端对象),负责系统中所有Activity的生命周期。
    ActivityManager:主要对运行中的Activity进行管理,实质上是通过AMS来管理Activity的。
    ActivityManagerProxy(AMP):一个代理对象(AMS的代理类),用于与AMS通信。
    ActivityManager管理Activity的本质:通过ActivityManagerNative的静态方法getDefault方法来得到AMP,通过AMP就可以和AMN进行通信,而AMN是一个抽象类,它会将功能交由它的子类AMS来处理,因此,AMP就是AMS的代理类。

    Launcher点击调整到某个应用流程

    1、Activity的启动过程

    Activity的启动时调用startActivity方法,最终会调用Instrumentation的execStartActivity方法。

    源码文件:
    frameworks/base/core/java/android/app/Instrumentation.java

    public ActivityResult execStartActivity(
              Context who, IBinder contextThread, IBinder token, Activity target,
              Intent intent, int requestCode, Bundle options) {
          ...
          try {
              intent.migrateExtraStreamToClipData();
              intent.prepareToLeaveProcess(who);
              int result = ActivityManager.getService()
                  .startActivity(whoThread, who.getBasePackageName(), intent,
                          intent.resolveTypeIfNeeded(who.getContentResolver()),
                          token, target != null ? target.mEmbeddedID : null,
                          requestCode, 0, null, options);
              checkStartActivityResult(result, intent);
          } catch (RemoteException e) {
              throw new RuntimeException("Failure from system", e);
          }
          return null;
      }
    

    execStartActivity方法实现在不同版本有所不同,7.0是通过ActivityManagerNative的getDefault来获取AMS的代理对象,8.0 逻辑封装到了IActivityManager中而不是ActivityManagerNative中。

    2、获取ActivityManager实例

    源码文件frameworks/base/core/java/android/app/ActivityManager.java

    public static IActivityManager getService() {
           return IActivityManagerSingleton.get();
       }
    
       private static final Singleton<IActivityManager> IActivityManagerSingleton =
               new Singleton<IActivityManager>() {
                   @Override
                   protected IActivityManager create() {
                       final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);//1
                       final IActivityManager am = IActivityManager.Stub.asInterface(b);//2
                       return am;
                   }
               };
    

    getService方法调用了IActivityManagerSingleton的get方法,我们接着往下看,IActivityManagerSingleton 是一个Singleton类。
    注释1处得到名为”activity”的Service引用,也就是IBinder类型的AMS的引用。接着在注释2处将它转换成IActivityManager类型的对象,这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译时自动生成的。
    IActivityManager.aidl的文件路径为:
    frameworks/base/core/java/android/app/IActivityManager.aidl
    要实现进程间通信,服务端也就是AMS只需要继承IActivityManager.Stub类并实现相应的方法就可以了。
    注意Android 8.0 之前并没有采用AIDL,而是采用了类似AIDL的形式,用AMS的代理对象ActivityManagerProxy来与AMS进行进程间通信,Android 8.0 去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的则是IActivityManager,它是AMS在本地的代理。

    回到Instrumentation的execStartActivity方法,ActivityManager通过getService方法转化获得ActivityManagerService(ActivityManagerService实现了IActivityManager.Stub),并且进入它的startActivityAsCaller方法。

    至此的时序图:


    应用启动时序图

    相关文章

      网友评论

          本文标题:Android应用启动的实质(二)

          本文链接:https://www.haomeiwen.com/subject/fuyuqctx.html