Activity启动过程

基本类介绍:

1.AMS提供的接口:

IActivityManager:继承了IInterface,它代表远程Service(即AMS)对外提供的服务
ActivityManagerNative:相当与Stub类,跨进程提供服务的实体,是一个抽象类
ActivityManagerService:ActivityManagerNative的实现类,跨进程提供的服务实际都由该类提供
ActivityManagerProxy:代理对象,同样实现了IActivityManager向普通进程提供AMS相同的服务

2.Client提供的接口:

ActivityThread:App启动的入口,AMS服务的Client实体
ApplicationThread:ActivityThread的内部类,继承Binder,Client通过这个对象向AMS提供接口调用
ApplicationThreadProxy:Service端Client的代理对象,service通过这个对象调用Client的方法

3.其他:

Instrumentation:负责发起Activity的启动、并具体负责Activity的创建以及Activity生命周期的回调,一个应用进程只会有一个Instrumentation对象,App内的所有Activity都持有该对象的引用。
ActivityStack:AMS通过ActivityStack管理所有的Activity
ActivityRecord:ActivityStack管理的对象,每个ActivityRecord对应一个Activity,里面封装了这个Acvitity的所有信息

Activity启动流程:

1.startActivity调用了startActivityForResult:

 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
 		@Nullable Bundle 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());
        }
 }

2.Instrumentation:

	//Context who:发起启动Activity的Context
	//IBinder contextThread:当前进程的ApplicationThread
	//IBinder token:AMS token
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        IApplicationThread whoThread = (IApplicationThread)contextThread;
    
        //ActivityManagerNative.getDefault()以单例的形式获取当前进程的AMS代理对象
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who, intent, token, target,requestCode, 0, ....);
        checkStartActivityResult(result, intent);
        return result;
    }

3.开始执行AMS端的逻辑
ActivityStackSupervisor和ActivityStack的方法管理活动栈,调用链太长,略

在正式启动Activity之前,ActivityStack会检查是否有Activity处于Resume状态,有的话要先使该Activity执行Pause;
停止Activity的方法是使用ApplicationThread代理跨进程通知那个Activity停止;

//className = com.android.server.am.ActivityStack
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
	...
    if (mResumedActivity != null) {
        pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
    }
}

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean dontWait) {
        ...
        //这个方法会调用ApplicationThread代理来跨进程使当前Activity停止
        prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait);
}

4.Client端Pause当前的Activity:

//className = ApplicationThread
public final void schedulePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    int seq = getLifecycleSeq();
    sendMessage(
            finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token,
            (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
            configChanges,
            seq);
}

handler收到消息会pause当前的的Activity,并立即通知AMS,请求启动新的Acitivity:

//className = android.app.ActivityThread
private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport, int seq) {
    ActivityClientRecord r = mActivities.get(token);
    ...
    if (r != null) {
        performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
        //通知AMS,请求启动新的Acitivity
    	ActivityManagerNative.getDefault().activityPaused(token);
    }
}

5.AMS端创建一个ActivityRecord并终于向Client发起请求打开新的Activity的请求:

 class ActivityStarter {
        private int startActivity(.....) {
        	...
        	//创建ActivityRecord 
            ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                    callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                    resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                    mSupervisor, options, sourceRecord);
        }
    }

//创建ActivityRecord的时候还会new一个apptoken,这个token在AMS端和Client端都是Acitvity的唯一标识
 ActivityRecord(...) {
        appToken = new Token(this);
        ........
}

调用ApplicationThread向Client请求开启Acitivity:

//className =  com.android.server.am.ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
   	...
   	//将新建的AMS token传递给Client端的Activity
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    return true;
}

6.ApplicationThread实体在Client进程执行新建ActivityClientRecord ,并使用Handler发送了一个消息

//className = ApplicationThread
public final void scheduleLaunchActivity(Intent intent,IBinder token, ...){
	ActivityClientRecord r = new ActivityClinetRecord();
	r.token = token;          							//AMS token对象的IPC代理
	r.intent = intent;
	...
	sendMessage(H.LAUNCH_ACTIVITY,r);
}

7.逻辑转移到H类中,用来处理H发送的消息:

/className = H
private class H extends Handler{
	public static final int LAUNCH_ACTIVITY = 100;
	...
	public void handleMessage(Message msg){
		switch (msg.what){
			case LAUNCH_ACTIVITY:
			ActivityClientRecord r = (ActivityClientRecord)msg.obj;
			Activity a = performLaunchActivity(r);		//在这个方法中完成了Activity的创建;
		}
	}
}

8.通过Instrumentation用反射创建Activity对象:

	ActivityInfo info = r.activityInfo;
	Activity activity = null;
	ClassLoader c = r.packageInfo.getClassLoader();
	activity = mInstrument.newActivity(c,className,r.intent)	//Instrument直接用类加载器和反射创建Activity

9.获取Applicationh和Instrumentation:

public Application makeApplication(Instrumentation instrumentation) {
	//应用内的页面跳转就直接返回已经存在的Application
	if (mApplication != null) {
		return mApplication;
	}
	ClassLoader classLoader = getClassLoader();
	//刚打开应用Application不存在,需要创建
	//Application也是通过Instrumentation创建的;
	return mActivityThread.mInstrumentation.newApplication(classLoader, ...)
}

10.创建ContextImpl,并执行attach方法:

	//在执行onCreat回调之前还要为新建的activity创建一个ContextImpl
	//可以看到每个activity都对应一个ContextImpl
	Context appContext = createBaseContextForActivity(r, activity);		//r是ActivityClientRecord
	//attach里创建了Activity对应的Window,并使得Activity与ContextImpl建立联系
	activity.attach(appContext,r.token, ...);								

11.执行Activity的onCreate方法:

	mInstarmentation.callActivityOnCreate(activity);

Token:
一个Activity对应一个Token,一个ActivityRecord和一个ActivityClientRecord;
(AMS进程端):先有new一个token,再把token注入ActivityRecord,这里的token是提供服务的实体对象;
(Client进程端):取出AMS传递的token注入新创建的ActivityClientRecord,最后才通过反射新建Activity,这里的token是AMS端token的代理对象;
Activity在通过反射创建出来之后,需要调用attach与ContextImpl进行关联,这个方法将token传递给Activity,Activity再将token传递给Window

ActivityThread:

class ActivityThread {          
	final ApplicationThread mAppThread = new ApplicationThread();
	final Looper mLooper = Looper.myLooper();
	final H mH = new H();
	//存储了所有的Activity,以IBinder作为key,IBinder是Activity在框架层的唯一表示
	final ArrayMap mActivities = new ArrayMap<>();
	//存储了所有的Service
	final ArrayMap mServices = new ArrayMap<>();
	//ActivityThread对象,拿到这个对象,可以反射调用这个类的需要的方法
	private static ActivityThread sCurrentActivityThread;

	public static void main(String[] args) {
		 Looper.prepareMainLooper();
		 ActivityThread thread = new ActivityThread();
    	 thread.attach(false); 		//系统应用为true,非系统应用为false;
		 Looper.loop();
	}
}

https://www.jianshu.com/p/88fe5f874aa1

你可能感兴趣的:(Activity启动过程)