根Activity的启动过程


《安卓进阶解密》读书笔记

这里分析的源码基于android-8.0.0_r4.

「根Activity的启动过程」和「Activity的启动_5.0」笔记记录的,有大部分过程是一样的.

概述

Activity启动过程中设计到的进程及其交互

根Activity的启动过程_1

时序图如下

根Activity的启动过程_2

这里将根Activity的启动划分为四部分

  1. Launcher请求AMS过程
  2. AMS判断根Activity所需的应用程序进程是否已经存在并启动,若不存在,则请求Zygote进程创建应用程序进程,详情查看《应用程序进程启动过程》的笔记。应用程序进程启动后,则进入下一个步骤
  3. AMS到ApplicationThread的调用过程
  4. ActivityThread启动Activity的过程

这里先看下第2部分,为什么会存在根Activity所需的应用进程已经启动的情况呢?比如现在要写一个音乐播放器App,第一次打开这个App,那么应用进程当然是未启动的,这时候为了启动根Activity,就需要先启动应用程序进程,再启动根Activity,现在它们都启动完毕,并且运行了一段时间,现在在程序中播放一首歌曲,音乐播放器放在Service中管理,现在按返回键,销毁所有的Activity,销毁完之后,会发现音乐还在播放,这时候虽然Activity都被销毁了,但是进程还是存活的,并且Service还是存活的,音乐仍然在播放,那么这时候,如果点击应用程序的快捷图标,将会启动根Activity,这种情况下就是根Activity所需的应用进程已经启动的情况。

另外,好像没有找到在哪里判断的「根Activity所需的应用程序进程是否已经存在并启动」的代码,是在ActivityStackSupervisor::startSpecificActivityLocked当中吗?

后面会讲解其余的三个部分。

相关类介绍

Instrumentation:仪表盘,具体到应用程序中是管理Activity的一个工具类,包括创建和启动ActivityActivity的生命周期方法都是由Instrumentation来控制的,一个进程只用一个Instrumentation实例

ActivityManagerServiceAndroid中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作

ActivityThread:管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activitiesbroadcasts及其相关的操作

ApplicationThread:用来实现ActivityManagerServiceActivityThread之间的交互,是ActivityThread的内部类

ActivityStack:负责单个Activity栈的状态和管理

ActivityStackSupervisor:负责所有Activity栈的管理

ActivityStarter:Android 7.0新加入的类,它是加载Activity的控制类

HActivityThread的内部类,继承至Handler,是应用程序进程中主线程的消息管理类

ProcessRecord:用于描述一个应用程序进程

ActivityRecord:用于描述一个Activity,用来记录一个Activity的所有信息

TaskRecord:用于描述一个任务栈

LoadedApk:用来描述已加载的APK文件

Activity:变量说明

  • mMainThreadActivityThread
  • mMainThread.getApplicationThread()ApplicationThread
  • ApplicationThreadActivityThread的一个内部类,这两个类在Activity启动的过程中都发挥着重要的作用

IBinder

这里简单说明根Activity启动时涉及到的Binder类、Binder接口,这部分内容在《Activity的启动_5.0》笔记中有记录过,但是Android 8.0之前,IActivityManager以及IApplicationThread的定义声明等并没有采用AIDL的形式,而是一种类似AIDL的形式,在Android 8.0中,采取的是一种AIDL的形式

Android 5.0的笔记

IActivityManager:

//Binder接口
public interface IActivityManager extends IInterface {...}

//Binder类,相当于Stub
public abstract class ActivityManagerNative extends Binder implements IActivityManager{.}

//Binder类的具体实现
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {...}

//Binder类的本地代理,相当于Proxy,定义在ActivityManagerNative里面,不同进程下,通过 //ActivityManagerNative的asInterface,即可将AMS「继承至Stub」转化为ActivityManagerProxy      //「Proxy」
class ActivityManagerProxy implements IActivityManager{...}

IApplicationThread:

//Binder接口
public interface IApplicationThread extends IInterface {...}

//Binder类,相当于Stub
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {}

//继承至Binder类,也就说这个相当于是Binder类的真正实现,相当于上面AMS的aidl逻辑分析中的Binder_1
private class ApplicationThread extends ApplicationThreadNative {...}

//代理对象如下,定义在ActivityThreadNative里面
class ApplicationThreadProxy implements IApplicationThread {...}

Android 8.0的变化

源码地址:IActivityManager.java.

public interface IActivityManager extends android.os.IInterface{
	...
    public static abstract class Stub extends android.os.Binder implements 
        android.app.IActivityManager{
    	...
        private static class Proxy implements android.app.IActivityManager{
        	...
        }
    }
}

源码地址:ActivityManagerService.java.

public class ActivityManagerService extends IActivityManager.Stub...{
    ...
}

形式上和《Android 开发艺术探索》介绍的一样。Android 8.0去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的是IActivityManager.Stub.ProxyActivityManagerService继承至IActivityManager.Stub

IApplicationThread应该也是这样。另外,ApplicationThreadActivityThread的内部类

这里没有去找源码,所以只能说应该,没找源码是因为aidl文件,是在编译的时候才转化为.java文件,源码怎么找嘛~~

PS:IActivityManager.java是通过代码的跳转链接找到的~~

Launcher请求AMS过程

当我们点击某个应用程序的快捷图标时,就会通过Launcher请求AMS来启动该应用程序,也就是启动根Activity,时序图如下

根Activity的启动过程_3

首先查看Launcher的继承关系

public class Launcher extends BaseActivity implements ... {...}

public abstract class BaseActivity extends Activity {...}

可以看出,Launcher就是Activity的子类.

首先是LauncherstartActivitySafely方法

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
 	...
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//该Flag表明根Activity会在新的任务栈启动
    ...
    startActivity(intent, optsBundle);
    ...
}

调用父类ActivitystartActivity方法

public void startActivity(Intent intent, @Nullable Bundle options) {
    ...
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }    
}

这里出现了startActivityForResult方法的两个重载,两个参数的那个方法,最终会调用到三个参数的,如下

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

这里查看三个参数的startActivityForResult方法

    # requestCode:如果requestCode >= 0,该Activity销毁时,requestCode值会返回到
    #              onActivityResult方法里 
	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);
           	...
        } else {
            ...
        }
    }
  • Activity mParent代表的是ActivityGroupActivityGroup最开始被用来一个界面中嵌入多个子Activity,后来在API 13 中被废弃了,使用Fragment代替,所以这里只用看mParent == null的逻辑

  • 这里传入的requestCode的值为-1,表明Launcher不需要知道Activity启动的结果

接着查看InstrumentationexecStartActivity方法

	public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
           Intent intent, int requestCode, Bundle options) {
        
    	IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        try {
            ...
            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;    
    }

这里通过ActivityManager.getService()获取到AMS的本地代理,远程调用AMSstartActivity,首先查看ActivityManager.getService()方法

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

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

这里通过单例类Singleton获取AMS的本地代理,Android 8.0之前 是通过ActivityManagerNativegetDefault来完成的,Android 8.0则将该逻辑封装到了ActivityManager当中

进程切换:Launcher进程 -> AMS所在进程(SystemServer进程)

AMS -> ApplicationThread

接下来的逻辑就进入了AMS所在进程.

时序图如下

根Activity的启动过程_4

下面只列举出几个重要的方法

首先是ActivityStarter的几个方法,先说一下ActivityStarter这个类,Android 7.0新加入的,是加载Activity的控制类,它会收集所有的逻辑,来决定如何将IntentFlags转换为Activity,并将ActivityTask以及Stack相关联.

ActivityStarter::startActivity,这里讲解的是第一个startActivity方法

private int startActivity(IApplicationThread caller ...) {
    ...
    ProcessRecord callerApp = null;
    if (caller != null) {
        callerApp = mService.getRecordForAppLocked(caller);
		...
    }
    ...
    //创建即将要启动的Activity的描述类ActivityRecord    
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
        callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
        resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
         mSupervisor, container, options, sourceRecord);
    //outActivity:ActivityRecord[]类型
    if (outActivity != null) {
        outActivity[0] = r;
    }    
}
  • caller:方法调用一路传来,是Launcher进程的Instrumentation::execStartActivity传来的,指向的是Launcher进程的ApplicationThread对象

  • callerApp:代表Launcher进程的ProcessRecord对象

ActivityStarter::startActivityUnchecked,该方法主要处理与栈管理相关的逻辑

private int startActivityUnchecked(...){
    ...
    //1.
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
       newTask = true;
       //2. 
       result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
    }
    ...
    //3.    
    mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                		mOptions);
}
  • 注释1:在Luncher::startActivitySafely中,会为根Activity的Intent设置FLAG_ACTIVITY_NEW_TASKFlag,在注释1中可以进入If语句

  • 注释2:内部会创建一个新的Activity任务栈,创建一个新的TaskRecord

  • 注释3:调用ActivityStackSupervisor::resumeFocusedStackTopActivityLocked

ActivityStackSupervisor::startSpecificActivityLocked

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        //1.获取即将启动的Activity的所在的应用程序进程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);

        //2.
        if (app != null && app.thread != null) {
            try {
                ...
                //3.    
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        // 如果进程不存在,则通过zygote创建应用进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
  • 注释2:app指的是即将启动的Activity的所在的应用程序进程;app.thread的类型是IApplicationThread,它的实现是要启动的Activity所在的应用程序进程的ActivityThread的内部类ApplicationThreadApplicationThread继承了IApplication.Stub,这里app.thread得到的是ApplicationThreadSystemServer进程的代理
  • 注释3:调用自身的realStartActivityLocked方法

ActivityStackSupervisor::realStartActivityLocked

	final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
    	...
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
            	System.identityHashCode(r), r.info,      
                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                r.persistentState, results, newIntents, !andResume,
                mService.isNextTransitionForward(), profilerInfo);
        ...
        return true;    
    }

这里调用了app.threadscheduleLaunchActivity,也就是调用应用程序进程的ApplicationThreadscheduleLaunchActivity方法

进程切换:AMS所在进程(SystemServer进程) -> 即将启动的Activity所在的应用程序进程

ActivityThread启动Activity的过程

目前代码逻辑运行在应用程序进程,时序图如下

根Activity的启动过程_5

ApplicationThread::scheduleLaunchActivity

        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor 
                voiceInteractor,int procState, Bundle state, PersistableBundle        					persistentState,List pendingResults, 
                List pendingNewIntents,boolean notResumed, 
                boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);
			
            //将启动Activity的参数封装成ActivityClientRecord
            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            ...
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

H类发送类型为H.LAUNCH_ACTIVITY的消息,并将ActivityClientRecord传递过去,H类是ActivityThread的内部类,继承至Handler,是应用程序进程中主线程的消息管理类

ActivityThread::sendMessage

    private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

由于ApplicationThread是一个Binder,它的调用逻辑运行在Binder线程池中,因此这里通过H,将代码逻辑切回主线程.

线程切换:应用程序Binder线程 -> 应用程序主线程

H::handleMessage

private class H extends Handler {
	...
    public void handleMessage(Message msg) {
    	if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
				//1.
                r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
                //2.
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            ...
        }
        ...
                
    }
}
  • 注释1:获取LoadedApk类型的对象赋值给ActivityClientRecordpackageInfo,应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadApk就是用来描述已加载的APK文件的
  • 调用ActivityThread::handleLaunchActivity

ActivityThread::handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
	...
    //启动Activity    
    Activity a = performLaunchActivity(r, customIntent);    
   	if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        //将Activity的状态设置为Resume
        handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished
                     && !r.startsNotResumed, r.lastProcessedSeq, reason);

        if (!r.activity.mFinished && r.startsNotResumed) {
            performPauseActivityIfNeeded(r, reason);
            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }  
        
     } else {
        try {
            //如果Activity为null,则通知AMS停止启动Activity
            ActivityManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
     }          
}

ActivityThread::performLaunchActivity

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //1.获取ActivityInfo类
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            //2.获取APK文件的描述类LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        //3.获取要启动的Activity的ComponentName
        //ComponentName保存了该Activity的包名和类名
        ComponentName component = r.intent.getComponent();
        ...
		//4.创建要启动的Activity的上下文环境
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //5.用加载器来创建该Activity的实例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }

        try {
            //6.尝试创建Application,makeApplication内部会调用Application的onCreate
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            ...

            if (activity != null) {
                ...
                appContext.setOuterContext(activity);    
                //7.初始化Activity   
                //内部包括创建PhoneWindow与Activity自身关联;关联ContextImpl...    
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);

                ...
                if (r.isPersistable()) {
                    //8.调用Instrumentation::callActivityOnCreate启动Activity
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            ...
        }

        return activity;
    }

注释4:创建Activity的上下文环境

 private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
     ...
     ContextImpl appContext = ContextImpl.createActivityContext(
           this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
     ...
     return appContext;
 }

Activityattach中会将ContextImpl进行关联

注释6:尝试创建Application,r.packageInfo的类型是LoadedApkLoadedApk::makeApplication

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        // 如果Application已经被创建过了,那么就不会再重复创建了,这意味着一个应用进程只有
    	// 一个Application对象
        if (mApplication != null) {
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;
       	...
           
        try {
            java.lang.ClassLoader cl = getClassLoader();
            ...
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            // Application对象的创建通过Instrumentation来完成,内部通过类加载器来实现
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                // 这里面会调用Application的onCreate()方法
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ...
            }
        }

        ...
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        return app;
    }

回到ActivityThreadperformLaunchActivity中,调用了Instrumentation::callActivityOnCreate

    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

Activity::performCreate

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle, persistentState);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

Activity::onCreate

    public void onCreate(@Nullable Bundle savedInstanceState,
            @Nullable PersistableBundle persistentState) {
        onCreate(savedInstanceState);
    }

调用到了void onCreate(@Nullable Bundle savedInstanceState) {...},至此,根Activity就启动了,即应用程序就启动了

可以结合《Activity的启动_5.0》的笔记一起看,那里关于一些细节记录得更详细一些~~

参考

《安卓进阶解密》