乐趣区

关于android:Activity的启动流程

考查要点:

  • 启动 Activity 会经验哪些生命周期回调
  • 冷启动大抵流程,波及哪些组件,通信过程是怎么样的?
  • Activity 启动过程中,生命周期回调的原理?

总的流程图:

1. 过程 A 与 AMS 的交互过程

此处以跨过程启动 Activity 剖析一下源码流程:

  1. A 调用 startActivity 时,须要与 AMS 交互,此时须要须要获取到 AMS 的代理对象 Binder 也就是上图的 AMP,通过 ActivityManagerNative.getDefault()取得,并调用 AMP 的 startActivity 办法,而后会通过 mRemote.transact 办法进行 Binder 通信,在 AMS 的 onTransact 办法外面会获取到申请的 Activity 参数信息:

    mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0);
    ...
    
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags){switch(code){
               case START_ACTIVITY_TRANSACTION:{startActivity(app,callingPackage,intent,...)
               }
           }
    }
    
  2. AMS 外面的 startActivity 办法最次要会去调用 startSpecificActivityLocked 函数,在此函数外面会去判断指标过程是否曾经存在,并且指标向 AMS 注册过它本人的 ApplicationThread 也就是上图 ATP 代理对象,如果这两个条件都满足会去调用 realStartActivityLocked 办法,这个办法咱们前面再看。如果上述条件不满足时,会去调用 mService.startProcessLocked(r.processName,…)办法启动过程。

2. AMS 启动指标过程 B

       ![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/2/7/1702043547d09967~tplv-t2oaga2asx-watermark.image)
  1. startProcessLocked 办法首先调用 Process.start(“android.app.ActivityThread”,)办法会向 Zygote 发送一个启动过程的申请,并告知 Zygote 过程启动之后,加载 ActivityThread 这个类的入口 main 函数,启动实现后返回过程的 pid,并向 AMS 的 Handler 发送一个提早音讯,为的是要求指标过程启动后,10 秒钟内须要向 AMS 报告,不然的话 AMS 就会革除指标过程的相干信息。
  2. Process.start 办法会去调用 startViaZygote(processClass,)函数,这个函数次要做了两件事,一件就是关上通往 Zygote 的 Socket,第二件事就是通过 Socket 发送启动过程参数。
  3. Zygote 端次要逻辑是在 runOnce 函数,函数内调用 Zygote.forkAndSpecialize(…)创立子过程,创立实现之后就别离在父过程和子过程外面做各自的事件
  4. 父过程通过 hanleParentProc(pid)把子过程的 pid 通过 Socket 发送给 AMS
  5. 子过程调用 handleChildProc 函数,做一些通用的初始化,比方启用 Binder 机制;执行应用程序的入口函数,也就是 ActivityThread 的 Main 函数
  6. ActivityThread 的 main 函数,外面会创立一个 ActivityThread 对象,并调用 thread.attach(false),为的是向 AMS 报到,下面第一条外面有提到。
  7. attach 办法外面,其实是一个跨过程的调用,首先通过

    IActivityManager mgr = ActivityManagerNative.getDefault();
    

    获取到 AMS 的 Binder 代理对象,而后调用

    mgr.attachApplication(mAppThread);
    

    mAppThread 是利用端的一个 Binder 对象 ApplicationThread,也就是最下面一张图的 ATP,这样 AMS 端就能够调用利用端了。

  8. attachApplication 办法外面,最次要有两个办法,一个是通过传入的 ApplicationThread 对象,调用 bindApplication 初始化 Application 对象,另一个就是通过

    mStactSupervisor.attachApplicationLoacked(app);
    

    初始化挂起的 Activity 对象。

  9. 在 attachApplicationLoacked 函数里,会调用

    ActivityRecord hr = stack.topRunningActivityLocked(null);
    

    其中要明确 AMS 外面有两个栈,一个是 Launch 桌面栈,一个就是非桌面栈 mFocusedStack, 此处的 stack 就是 mFocusedStack,它会将栈顶的 ActivityRecord 返回进去,咱们的指标 Activity 早就搁置在了栈顶,只是始终没有初始化。而后调用

    realStartActivityLocked(hr,app,true,true);
    

    办法,来启动 Activity,如果咱们不是启动另外一个过程,而是同一过程,那么这第二大部分就不会存在了,而是间接调用 realStartActivityLocked 办法。

3. 利用端 Activity 启动的几个步骤

  1. realStartActivityLocked 函数会调用 app.thread.scheduleLaunchActivity(new Intent(r.intent),…); 也就是通过之前注册的 Binder 对象 ATP,调用 scheduleLaunchActivity 函数,在 scheduleLaunchActivity 函数外面:

    ActivityClientRecord r = new ActivityClientRecord();
    ...
    sendMessage(H.LAUNCH_ACTIVITY,r);
    

    封装了一个 ActivityClientRecord 音讯,而后丢到主线程的 Handler(mH)里。

  2. 在主线程外面

    final ActivityClientRecord r =(ActivityClientRecord)msg.obj ;
    r.packageInfo = getPackageInfoNoCheck(...);
    handleLaunchActivity(r,null);
    

    getPackageInfoNoCheck 函数次要是用来生成一个 LoadedApk 对象,它用来保留咱们的 apk 信息,因为前面咱们须要一个 ClassLoader 去加载 Apk 外面的 Activity 类,所以这里提前准备好。

  3. handleLaunchActivity 外面分为两个局部,一个是 performLaunchActivity 函数,一个是 handleResumeActivity 函数。
  4. performLaunchActivity

    Activity activity = mInstrumentation.newActivity(...);
    
    // 返回之前创立好的
    Application app = r.packageInfo.makeApplication(false,mInstrumentation);
    
    // 生成 ContextImpl
    Context appContext = createBaseContextForActivity(r,activity);
    
    // 给 activity 绑定上下文和一些初始化的工作, 如 createPhoneWindow
    activity.attach(appContext,...);
    
    mInstrumentation.callActivityOnCreate(activity,r.state); // 生命周期的 OnCreate
    
    activity.performStart();    // 生命周期的 OnStart
    
    return activity
    
  5. handleResumeActivity:

    -> r.activity.performResume()     
       -> mInstrumentation.callActivityOnResume(this);
         -> activity.onResume()
    

相干视频举荐

【安卓面试合集】startActivity 面试点 01
Android(安卓)开发零根底从入门到精通

本文转自 https://juejin.cn/post/6844904058688372750,如有侵权,请分割删除。

退出移动版