根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所需的应用进程已经启动的情况。

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

相关类介绍

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<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @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<ResultInfo> pendingResults, 
                List<ReferrerIntent> 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》的笔记一起看,那里关于一些细节记录得更详细一些~~

参考

《安卓进阶解密》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值