Android笔记(十六)Activity启动

Activity启动分为两种情况

  • Activity所在进程不存在,冷启动
  • Activity所在进程存在于后台

针对于这两种情况,我们都可以对此用一套流程来描述,针对冷启动情况,其中会添加一部分创建ActivityThread的流程
还是先上图,图片出处GitYuan
Android笔记(十六)Activity启动_第1张图片
假设在图片流程之前,我们做的是点击桌面按钮操作,那么会去执行activity的startActivity操作,该方法里面会通过Instrumetation这个大管家去调用其他方法

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            ...
}

在这个方法里面才是真正地通过AMS操作activity,注意,此时的Context,ContextThread,Token都是发起方Activity的,不是被调起方的。其中的ContextThread为发起方所在的ActivityThread中的ApplicationThread属性,该属性为Binder类型,用来和AMS进行交互

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
}

下面会通过ActivityStack类中的封装,执行startActivityMayWait()

 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);

在ActivityStarter.java的startActivityMaywait()方法中,再调用startActivityLocked()方法,进一步调用startActivityUnchecked()。用图表示如下

  • Instrumentation.execStartActivity()
    • AMS.startActivity()
      • ActivityStarter.startActivityMayWait()
        • ActitivityStarter.startActivityLocked()
          • ActitivityStarter.startActivityUnchecked()(此处设计到启动模式,另外还会打印EventLog:Activity Oncreate)

接着上图,AMS后面会将Activity的处理放到ActivityStackSupervisor类中。其中值得注意的几个地方如下:

  • startActivityUncheckedLocked方法中会涉及到LaunchMode启动模式相关
  • resumeTopActivityLocked方法中会去将当前的可见Activity设置为Pause状态
  • startSpecialActivity()方法中会去判断要启动的Activity对应的进程是否存在,如果存在,
    1. 调用realStartActivityLocked()
      此处会判断是不是当前activity已经处于pause状态,如果还没有完成pause工作,将会打印Skipping start of r some activitys pausing的log
    2. 打印AM_RESTART_ACTIVITY
    3. ApplicationThread执行scheduleLaunchActivity,此处还在ActivityStackSupervisor中执行,也就是说运行到此时是在system_server进程中,通过IPC调用call到了应用进程,我需要通过IAppicationThread通过Handler的方式去通知ActivtiyThread,ApplicationThread作为ActivityThread的内部类,可以和ActivityThread进行通信
    4. ActivityThread执行handleLaunchActivity
    5. handleLaunchActivity中执行performLaunchActivity()方法,该方法中会new activity new window activity.attach(window) onCreate() onStart()。其中new activity是通过反射的方式来获取到的;window的创建和绑定都在Activity.attach()中完成的;onCreate()和onStart()方法都是通过mInstrumentation来回调的;同时attach()中还完成了attachBaseContext操作。
    6. handleResumeLunchActivity(),该方法中先执行performResumeAtivity(),进一步调用时,可能会执行performRestart(),一定会走performResume()最终调用onResume();然后是对window的处理,将前面已经添加成功的根view,也就是decorView添加到wm中。wm.addView(decor,l);
    7. onResume

如果不存在该进程
1. AMS.startProcessLocked()
2. zygote fork new process;Process.start()
3. ActivityThread.main()
4. Looper.prepareMain()/ActivityThread.atttach(false),Loop.loop()
5. AMS.attachApplication(IAppicationThread)建立起ActivityThread和AMS之间的联系,在AMS.attachApplication()方法中,会调用thread.bindApplication(进程相关属性),调用完后通过Handler传递给ActivityThread执行handleBindApplication操作。AMS.attachApplication()中还有一件重要的事情就是最终调用realStartActivity()。具体过程为:

//AMS中的attachApplication()方法
void attachApplication(){
	...
	thread.bindApplication(...);
	...
	mStackSupervisor.attachApplicationLocked();//最终调用realStartActivity()
}

-----2020新增----

新的Activity生命周期处理流程

后来, Android引入了 JetPacket框架后,新增了 Life Cycle念,可以让应用通过 addobserver的方式方便地监听到 activity /fragment的生命
周期。同时在启动 acitivity的地方做出了一些修改,目的是为了让activity的生命周期操作从原来的 ActivityThread中到剥离出来,使用新的类来管理生命周期,如 LaunchActivityltem/ResumeActivityltem/ PauseAcitivtyltem等。这些类都在 android/app/transilatonserve径下。原来的 acitivty启动流程走到 ActivityStackSuperVisor走到 realStartActivity后,里面调用了ATMS.gstlifecyclemanager.scheduleTransaction(clinet) 方法,其中,client有上述item信息。这样便开始了生命周期行为。 LaunchActivityltem中持有 Application Thread,可以方便地和app测进行交互
从ActivityThread.mH中的代码来看,之前的activity生命周期相关的launch message处理交给了EXECUTE_TRANSACTION处理。
这些XActivityItem都继承自ActivityLifecycleItem extends ClientTransactionItem
Android笔记(十六)Activity启动_第2张图片
上面说的用来管理这些单独ActivityLifeCycleItem的类如下:

ClientTransaction.java

Android笔记(十六)Activity启动_第3张图片

TransactionExecutor.java

Android笔记(十六)Activity启动_第4张图片

你可能感兴趣的:(andorid)