Activity的启动_5.0

源码分析基于 Android 5.0.0_r2

这里分析Activity的启动,沿着思路:在一个app的已有的Activity之上,启动另外一个Activity,这两个Activity属于同一个app、同一个进程

整体流程

相关类介绍

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

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

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

ApplicationThread:用来实现ActivityManagerServiceActivityThread之间的交互

ApplicationThreadProxyApplicationThread 在服务端的代理,AMS就是通过该代理与ActivityThread进行通信的

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

ActivityStackSupervisor:负责所有Activity栈的管理

Activity:变量说明

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

mMainThread实际上是ActivityThread对象,ActivityThread,就是主线程,也就是UI线程,它是在App启动时创建的,它代表了App应用程序。那Application类岂不是被架空了?其实,Application对我们App开发人员来说也许很重要,但是在Android系统中还真的没那么重要,他就是个上下文。Activity不是有个Context上下文吗?Application就是整个ActivityThread的上下文。

—摘抄自博客 Android Launcher 启动 Activity 的工作过程

startActivityForResult

调用ActivitystartActivity(XXX)

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

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

这里startActivity(intent,options)无论哪种情况,最终都是调用到startActivityForResult(intent, requestCode,options)

    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            //着重看mInstrumentation.execStartActivity(...)这一段代码
            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());
            }
            if (requestCode >= 0) {
            // 如果这个Activity启动需要下一个Activity的结果
            // 则会在下一个Activity的结果获得之前使得这个Activity不可见。
                mStartedActivity = true;
            }

            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
            if (decor != null) {
                decor.cancelPendingInputEvents();
            }
            
       } else {
			......
        }
        ......
    }

Activity mParent代表的是ActivityGroupActivityGroup最开始被用来一个界面中嵌入多个子Activity,后来在API 13 中被废弃了,使用Fragment代替,所以这里只用看mParent == null的逻辑

Instrumentation

    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
        
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...省略ActivityMonitors相关代码
        try {
            ...
            //着重看这里的代码
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                               intent.resolveTypeIfNeeded(who.getContentResolver()),
                               token, target != null ? target.mEmbeddedID : null,
                               requestCode, 0, null, options);
            //检查启动Activity的结果(可能会抛出异常,例如在AndroidManifest中待启动的Activity
            //没有注册)
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }

AMSIActivityManager的关系

代码表示:

//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{...}

AIDL理解:也就是说,之前《开发艺术探索 - 第二章》中,写一个aidl文件,就有对应的Binder接口、Stub、Proxy,然后我们自己在远程服务端Service自己去继承Stub实现Binder类「暂时称为Binder_1」,然后本地端bindService,将获取的Binder_1对象,通过asInterface的方法,转化为本地代理Proxy。对应到这里,IActivityManager、ActivityManagerNative、ActivityManagerProxy就相当于是aidl文件自动生成的

Binder接口、Stub、Proxy,只是这里它分开写了,即Binder接口写一个,然后Stub和Proxy写一起,这里ActivityManagerService相当于Binder_1

关系图如下:

1613361628456

所以说,ActivityManagerService简称「AMS」就是IActivityManager的具体实现

接着看上面的execStartActivity(xxx),其中ActivityManagerNative.getDefault()获取的是什么

	//ActivityManagerNative中
	static public IActivityManager getDefault() {
        return gDefault.get();
    }

	//ActivityManagerNative中
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            ...
            IActivityManager am = asInterface(b);
            ...
            return am;
        }
    };

AMS这个Binder对象采用单例模式对外提供,Singleton是一个单例的封装类,第一次调用它的get方法时,它会通过create方法来初始化AMS这个Binder对象。这里获取的对象其实是一个Binder代理,即通过ServiceManager.getService(xxx)获取的应该是远程的Stub类,也就是AMS,然后通过Stub.asInterface(xxx),获取AMS的代理类Proxy,这个代理类就是ActivityManagerProxy,简称AMP

所以上面InstrumentationexecStartActivity(xxx),最终就是调用到了AMSstartActivity(xxx),在这里,调用就从Instrumentation转到了AMS

好,先岔开下话题,看Instrumentation.execStartActivity(xxx)两个重要的参数:IBinder contextThreadIBinder token

 public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {...}
IBinder contextThread

IBinder contextThread:在Activity中,传入的是mMainThread.getApplicationThread(),其实就是ApplicationThread

//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 {...}

从这里看出ApplicationThread,就是用于进程间通信的一个Binder对象

它的本地代理对象如下,定义在ActivityThreadNative里面,不同进程下,通过ActivityThreadNativeasInterface即可将ApplicationThread「继承至Stub」转化为ApplicationThreadProxy 「Proxy」

class ApplicationThreadProxy implements IApplicationThread {...}

这一块的aidl逻辑,和上面分析的IActivityManager、ActivityManagerService那一块的aidl逻辑是一样的

IBinder token

这个token对象其实是在Activityattach(xxx)的时候传入的,也就是Activity创建与关联的时候,它是个Binder对象,代表了Launcher这个Activity,这里通过Instrumentation传给AMSAMS查询后,就知道是谁向AMS发起请求了。Activityattach(xxx)如下

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor) {..}

contextThread和token这两个参数是伏笔,传递给AMS,以后AMS想反过来通知Launcher,就能通过这两个参数,找到Launcher。

AMS.startActivity(xxx)

进程切换第一次:app进程 -> 系统进程的Binder线程池

好,回到刚刚的话题,即调用从Instrumentation转到了AMS,从AMS开始,就是在远程端「系统进程」了

	@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,resultWho, requestCode, startFlags, profilerInfo, options,UserHandle.
getCallingUserId());
    }

调用AMSstartActivityAsUser(xxx)

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,false, ALLOW_FULL_ONLY, "startActivity", null);
        
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, userId, null, null);
    }

ActivityStack(Supervisor)

上面调用了ActivityStackSupervisorstartActivityMayWait,接下来的调用过程如下

image-20210928182837045
1.ActivityStackSupervisor

先看一下ActivityStackSupervisorstartActivityMayWait

    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
            Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) {
        ......
        //根据intent在系统中找到合适的应用的activity,如果有多个activity可选择,
        //则会弹出ResolverActivity让用户选择合适的应用。
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, 	                                                                   profilerInfo,userId);

        ......
        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options,
                    componentSpecified, null, container, inTask);
        
        return res;
}

调用到ActivityStackSupervisorstartActivityLocked(xxx)

    final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer 			container,TaskRecord inTask) {
  
        ......
        //创建ActivityRecord对象,ActivityRecord作为Activity的记录者,每次启动一个Activity
        //会有一个对应的ActivityRecord对象,表示Activity的一个记录
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid,        								callingPackage,intent, resolvedType, aInfo, 			     							 mService.mConfiguration, resultRecord, resultWho,requestCode, 							   componentSpecified, this, container, options);
   		......
        //调用到ActivityStackSupervisor的startActivityUncheckedLocked(xxx)
        //这里传入了刚刚创建的ActivityRecord r对象
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, 				    							voiceInteractor,startFlags, true, options, inTask);
        
    }

ActivityStackSupervisorstartActivityUncheckedLocked(xxx)方法比较复杂,应该是对启动的flag和启动模式等的处理,这里不深入分析,其中会调用到ActivityStackresumeTopActivityLocked(xxx)方法

    final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
    			IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 				 int startFlags,boolean doResume, Bundle options, TaskRecord inTask) {
     ...
     if (doResume) {
         targetStack.resumeTopActivityLocked(null, options);
     }
     ... 
         
    }
2.ActivityStack

调用到了ActivityStackresumeTopActivityLocked(xxx)

    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            inResumeTopActivity = false;
        }
        return result;
    }

调用到了ActivityStackresumeTopActivityInnerLocked(xxx)

    final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    	...
        //获取要启动的Activity    
        ActivityRecord next = topRunningActivityLocked(null);    
        ...
        --------------------------------------------------------------------------    
        // 我们需要先去对当前正在显示的Activity进行onPause操作,然后要启动的Activity才能
        // 进行onResume操作    
        boolean dontWaitForPause = 			  	                                                       			 (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = 	  																				 mStackSupervisor.pauseBackStacks(userLeaving,true,dontWaitForPause);
        //mResumedActivity的类型是ActivityRecord,指向上一次启动的Activity
        if (mResumedActivity != null) {
            // 通知Launcher进入pause状态
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + 												mResumedActivity);
        }
        --------------------------------------------------------------------------
        ...
        //调用到了这里,这里传入了要启动的Activity的ActivityRecord    
        mStackSupervisor.startSpecificActivityLocked(next, true, true); 
    }

这里主要处理了一些Activity栈相关的东西,主要看两部分的内容

  • 让上一个Activity进入onPause状态
  • 调用了ActivityStackSupervisorstartSpecificActivityLocked(xxx)
  1. 先看Activity进入onPause状态

进程切换第二次:系统进程 -> app进程Binder线程池

先看ActivityStackstartPausingLocked(...)

    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,boolean dontWait) {
        ...
        ActivityRecord prev = mResumedActivity;
        ...
        // prev.app:ProcessRecord
        // prev.app.thread:IApplicationThread    
        if (prev.app != null && prev.app.thread != null) {
           prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                   userLeaving, prev.configChangeFlags, dontWait);
        } else {
           ...
        }
    
    }

这里的prev.app.threadapp进程在系统进程的binder代理,即ApplicationThreadProxy,所以这里是第一次从系统进程切回到app进程的binder线程池当中,然后binder的真正实现ApplicationThread是在app进程实现的,看下ApplicationThreadschedulePauseActivity(...)「运行在app进程的binder线程池里面」

    public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
        sendMessage(
            finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token,
            (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
            configChanges);
    }

ActivityThreadsendMessage(...)

    private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, 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; //在这里what = PAUSE_ACTIVITY
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

可以看出,通过ActivityThread自定义的Handler发送了消息,这个自定义的Handler

// ActivityThread的内部类 
private class H extends Handler {...}

// 在ActivityThread中的变量定义
final H mH = new H();

app进程Binder线程池 -> app进程主线程

H mH获取的Looper应该是主线程的Looper,所以这里mH是主线程的Handler,这里通过Handler的消息机制,将Activity的启动从app进程的Binder线程池中切换到app进程的主线程中

HhandleMessage处理如下

    public void handleMessage(Message msg) {
        switch (msg.what) {
        	...
            case PAUSE_ACTIVITY:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,(msg.arg1&2) != 0);
                maybeSnapshot();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
             ...
        }
    }    

调用了ActivityThreadhandlePauseActivity

private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) {
    ...
    performPauseActivity(token, finished, r.isPreHoneycomb());
	...
}

ActivityThreadperformPauseActivity(...)

    final Bundle performPauseActivity(IBinder token, boolean finished,
            boolean saveState) {
        ActivityClientRecord r = mActivities.get(token);
        return r != null ? performPauseActivity(r, finished, saveState) : null;
    }

	// 调用到下面
	final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState) {
        ...
        if (!r.activity.mFinished && saveState) {
            // 最终会调用到Activity的onSaveInstanceState(Bundle outState)
            callCallActivityOnSaveInstanceState(r);
        }
        ...
        // 最终会调用到Activity的onPause()    
        mInstrumentation.callActivityOnPause(r.activity);
        ...
    }

callCallActivityOnSaveInstanceState(...)最终会调用到ActivityonSaveInstanceState(Bundle outState)

mInstrumentation.callActivityOnPause(...)最终会调用到ActivityonPause

InstrumentationcallActivityOnPause(...)

    public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }

ActivityperformPause(...)

final void performPause() {
	...
    onPause();
	...
}

这里Activity的生命周期方法onSaveInstanceState(Bundle outState)onPause(...)由于前面的进程和线程切换,所以均是在app进程的主线程进行的

  1. 调用ActivityStackSupervisorstartSpecificActivityLocked(xxx)

进程切换第三次:app进程 -> 系统进程Binder线程池

前面切换到app进程时,系统进程的线程是挂起状态,等app进程执行完上面所说的,就自动又回到系统进程,之后执行如下面

3.ActivityStackSupervisor

这里的调用又从ActivityStack回到了ActivityStackSupervisor,看ActivityStackSupervisorstartSpecificActivityLocked(xxx)

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // 这是要启动的Activity的进程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);
	
        // 如果要启动的Activity的进程已经存在
        if (app != null && app.thread != null) {
            try {
                ...
                // 调用realStartActivityLocked(xxx)
                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.
        } (--if结束)

        // 如果进程不存在,则通过zygote创建应用进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

这里分析的是:在一个app的已有的Activity之上,启动另外一个Activity,这两个Activity属于同一个app、同一个进程。所以它会走到if里面,调用到realStartActivityLocked(xxx),而不会走到mService.startProcessLocked(xxx),那么什么情况下会走到这里呢?比如现在要在自己的app启动淘宝appMainActivity,那么淘宝app所在的进程当然是不存在的,那么就不会走到if里面,而是通过mService.startProcessLocked(xxx)创建新的进程。

当然,这里分析的是:在一个app的已有的Activity之上,启动另外一个Activity,这两个Activity属于同一个app、同一个进程。创建进程的那一条逻辑可以后面再看看。所以接下来就看看ActivityStackSupervisorrealStartActivityLocked(xxx)

    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, new 				Configuration(mService.mConfiguration),r.compat, r.task.voiceInteractor, 				app.repProcState, r.icicle, r.persistentState,results, newIntents,!andResume, 			  mService.isNextTransitionForward(),profilerInfo);
        ......
    }

这里的app类型是ProcessRecordapp.thread的类型是IApplicationThread,从前面的「笔记」 IBinder contextThread那里可以得知,IApplicationThread的真正实现是ApplicationThread

realStartActivityLocked(xxx)ProcessRecord app参数,是在startSpecificActivityLocked(xxx)的下面代码获取并传送到realStartActivityLocked(xxx)方法里的

	// 这是要启动的Activity的进程
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

app它代表了要启动的Activity的进程

进程切换第四次:系统进程 -> app进程Binder线程池

关键点:这个app代表的是Activity要启动的进程,这时候通过app.thread获取的IApplicationThread的真正实现应该是在启动Activity的本地端实现的,更确切的说,这个app.thread获取的应该是IApplicationThread的代理类ApplicationThreadProxy,其真正的实现类应该是在本地端实现的ApplicationThread,也就是scheduleLaunchActivity(...)方法应该是在本地端的Binder线程池里面执行的。所以,从这里就将Activity的启动又从系统进程切换到app进程「也就是本地端」了

ApplicationThreadProxy

接上面的系统进程 -> app进程的Binder线程池

ApplicationThreadActivityThread的内部类,看下它的scheduleLaunchActivity(xxx)方法

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

        updateProcessState(procState, false);

        ActivityClientRecord r = new ActivityClientRecord();

        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.voiceInteractor = voiceInteractor;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;
        r.persistentState = persistentState;

        r.pendingResults = pendingResults;
        r.pendingIntents = pendingNewIntents;

        r.startsNotResumed = notResumed;
        r.isForward = isForward;

        r.profilerInfo = profilerInfo;

        updatePendingConfiguration(curConfig);

        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

这个方法主要是发送了一个启动Activity的消息给Handler处理

app进程的Binder线程池 -> app进程的主线程

    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);
    }

这里的mH类型是 final H mH = new H();

H继承至Handler,是ActivityThread的内部类,如下

	private class H extends Handler {
        public static final int LAUNCH_ACTIVITY = 100;
        ...
        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;

                    //  r.packageInfo的类型是LoadedApk
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                ... 
            }
            ...
        }  
        ...
    }

关键点:前面已经从系统进程切回到了app进程的Binder线程池中运行,然后这里的app进程的ActivityThread又代表着UI线程,即主线程,ActivityThread的自定义的Handler定义为final H mH = new H(),这里获取的Looper应该就是主线程的Looper,所以这个自定义Handler应该是主线程的Handler,也就是这里通过Handler的消息机制,将Activity的启动又从app进程的Binder线程池中切换到app进程的主线程中,在app进程的主线程中进行Activity的启动,所以后面的生命周期方法onCreateonStartonResume这些都是运行app进程的主线程中

handleLaunchActivity

HhandleMessage在处理LAUNCH_ACTIVITY这个消息的时候,调用了外部类ActivityThreadhandleLaunchActivity(xxx)方法

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		...
        // performLaunchActivity(xxx)方法最终完成了Activity对象的创建和启动过程
        Activity a = performLaunchActivity(r, customIntent);  
        
        if (a != null) {
            ...
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);    
        } else {
            // If there was an error, for any reason, tell the activity
            // manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
            } catch (RemoteException ex) {
                // Ignore
            }
        }
        
    }

正常情况下,a != null,会调用handleResumeActivity(xxx)方法,来调用被启动的ActivityonResume的生命周期方法

performLaunchActivity

这个方法里,最终会调用到ActivityonCreate(xxx)onStart(xxx)onRestoreInstanceState(xxx)

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		// 1.获取待启动的Activity的组件信息
    	ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
    
    	// 2.使用类加载器创建Activity对象
  	    Activity activity = null;
        try {
            // 获取类加载器
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            // 通过类加载器来创建Activity对象
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }
    
    	...
        // 3.通过LoadedApk的makeApplication(xxx)方法来尝试创建Application对象    
        Application app = r.packageInfo.makeApplication(false, mInstrumentation); 
    	
    ...
    // 4.创建ContextImpl对象,并通过Activity的attach方法来完成一些重要数据的初始化   
	if (activity != null) {
   	 	 // contextImpl对象   
     	Context appContext = createBaseContextForActivity(r, activity);
    	CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
    	Configuration config = new Configuration(mCompatConfiguration);
     	if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "+ r.activityInfo.name + 														"with config " + config);
     	activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, 						r.intent, r.activityInfo, title, r.parent,r.embeddedID, 		     					r.lastNonConfigurationInstances, config,r.voiceInteractor);
 		 ...
     	// 5.调用Activity的onCreate方法    
     	if (r.isPersistable()) {
        	  mInstrumentation.callActivityOnCreate(activity, r.state, 		  			                                                     r.persistentState);
     	} else {
        	  mInstrumentation.callActivityOnCreate(activity, r.state);
     	}
     	...   
        // 6.调用Activity的onStart方法
        if (!r.activity.mFinished) {
            activity.performStart();
            r.stopped = false;
        }
        ...
        // 7.调用Activity的onRestoreInstanceState方法
        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
        ...  
    }
    ...    
}

ActivityThreadperformLaunchActivity方法主要完成下面几件事情

  1. ActivityClientRecord中获取待启动的Activity的组件信息
 		ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
  1. 通过InstrumentationnewActivity方法,使用类加载器创建Activity对象
        Activity activity = null;
        try {
            // 获取类加载器
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            // 通过类加载器来创建Activity对象
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

newActivity(xxx)代码如下

    // 通过类加载器来创建Activity对象
	public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }
  1. 通过LoadedApkmakeApplication(xxx)方法来尝试创建Application对象
//ActivityThread.performLaunchActivity里
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

//r.packageInfo的类型是LoadedApk,其相应方法如下
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
    // 如果Application已经被创建过了,那么就不会再重复创建了,这意味着一个应用进程只有
    // 一个Application对象
    if (mApplication != null) {
        return mApplication;
    }
    
    Application app = null;
    ...
    java.lang.ClassLoader cl = getClassLoader();
    ...
    // Application对象的创建也是通过Instrumentation来完成的,过程和Activity的创建一样,
    // 都是通过类加载器来实现的    
    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    ...
    mApplication = app;
    
    
    if (instrumentation != null) {
   		 try {
             // 这里面会调用Application的onCreate()方法
             instrumentation.callApplicationOnCreate(app);
         } catch (Exception e) {
            ...
         }     
    }
    ...
    return app;    
}
  1. 创建ContextImpl对象,并通过Activityattach方法来完成一些重要数据的初始化
 	// 这个activity对象,就是前面通过类加载器创建的对象
	if (activity != null) {
     // contextImpl对象   
     Context appContext = createBaseContextForActivity(r, activity);
     CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
     Configuration config = new Configuration(mCompatConfiguration);
     if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "+ r.activityInfo.name + " 											with config " + config);
     activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, 						r.intent, r.activityInfo, title, r.parent,r.embeddedID, 		     					r.lastNonConfigurationInstances, config,r.voiceInteractor);
 	 ......
     if (r.isPersistable()) {
          mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
     } else {
          mInstrumentation.callActivityOnCreate(activity, r.state);
     }
     ......        
    }

Activityattach如下

    final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
        // ContextImpl和Activity建立关联
        attachBaseContext(context);
        ...
        // 创建PhoneWindow对象    
        mWindow = PolicyManager.makeNewWindow(this);
        // 设置回调接口
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode!=WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED){
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }    
        ...
        // 为PhoneWindow设置WindowManager    
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        // 获取WindowManager并赋值给Activity的成员变量mWindowManager,
        // 这样在Activity就可以通过getWindowManager方法来获取WindowManager
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }

attach(xxx)里,会建立ContextImplActivity的关联,还会完成Window的创建并通过接口回调的方式建立ActivityWindow的关联,这样当Window接收到外部输入事件后就可以将事件传递给Activity

  1. 调用ActivityonCreate

在执行完attach之后,performLaunchActivity会调用下面的代码

	 if (r.isPersistable()) {
          mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
     } else {
          mInstrumentation.callActivityOnCreate(activity, r.state);
     }

在这里,最终会调用到ActivityonCreate(Bundle savedInstanceState) {...}

  1. 调用ActivityonStart

之后,ActivityThreadperformLaunchActivity(xxx)里面,还有下面的一段代码

	if (!r.activity.mFinished) {
        activity.performStart();
        r.stopped = false;
    }

ActivityperformStart(xxx)

    final void performStart() {
        ...
        mInstrumentation.callActivityOnStart(this);
        ...
    }

InstrumentationcallActivityOnStart(xxx)

public void callActivityOnStart(Activity activity) {
     activity.onStart();
}
  1. 调用ActivityonRestoreInstanceState

之后,ActivityThreadperformLaunchActivity(xxx)里面,还有下面的一段代码

mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);

InstrumentationcallActivityOnRestoreInstanceState(xxx)

	public void callActivityOnRestoreInstanceState(Activity activity, Bundle 			savedInstanceState) {
      activity.performRestoreInstanceState(savedInstanceState);
	}	

ActivityperformRestoreInstanceState(xxx)

    final void performRestoreInstanceState(Bundle savedInstanceState) {
        onRestoreInstanceState(savedInstanceState);
        restoreManagedDialogs(savedInstanceState);
    }

可以看出,这里就调用了ActivityonRestoreInstanceState(xxx)

handleResumeActivity

在这个方法里,会调用到ActivityonResume(xxx)

handleLaunchActivity(xxx)在调用了performLaunchActivity(xxx)之后,会调用handleResumeActivity(xxx),在handleResumeActivity(xxx)里面,最终会调用到ActivityonResume(xxx)makeVisible(xxx),具体过程如下

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume) {
    ...
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    ...
    r.activity.makeVisible();
    ...
}

performResumeActivity(xxx)最终会调用到ActivityonResume

makeVisible(xxx)会完成ActivityDecorView的添加和显示的过程

performResumeActivity(xxx)的具体调用过程如下

// ActivityThread
public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide) {
    ...
    r.activity.performResume();
    ...
}

// Activity
final void performResume() {
    ...
    mInstrumentation.callActivityOnResume(this);
    ...
}

//Instrumentation
public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    //调用到了Activity的onResume()
    activity.onResume();
    ...
}

至此,就完成了整个Activity的启动!

流程图

Activity启动_5.0_整体流程

总结

IBinder总结

整个Activity启动的IBinder出现的两个BinderIApplicationThreadIActivityManager,这里再次对它们进行总结一下

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{...}

IActivityManager定义的方法,只列出一部分

public interface IActivityManager extends IInterface {
    public int startActivity(...) throws RemoteException;
    public int startActivityAsUser(...) throws RemoteException;
    public int startActivityAsCaller(...) throws RemoteException;
    public WaitResult startActivityAndWait(...) throws RemoteException;
    ...
    public boolean finishActivity(...) throws RemoteException;
    public void finishSubActivity(...) throws RemoteException;
    ...
    public void finishReceiver(...) throws RemoteException;
    public void attachApplication(...) throws RemoteException;
    public void activityResumed(...) throws RemoteException;
    public void activityIdle(...) throws RemoteException;
    public void activityPaused(...) throws RemoteException;
    public void activityStopped(...) throws RemoteException;
    ...
    public ComponentName startService(...) throws RemoteException;
    public int stopService(...) throws RemoteException;
    public boolean stopServiceToken(...) throws RemoteException;
    public void setServiceForeground(...) throws RemoteException;
    public int bindService(...) throws RemoteException;
    public boolean unbindService(...) throws RemoteException;
    ...
}

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 {...}

IApplicationThread定义的方法,只列出一部分

public interface IApplicationThread extends IInterface {
    void schedulePauseActivity(...) throws RemoteException;
    void scheduleStopActivity(...) throws RemoteException;
    void scheduleWindowVisibility(...) throws RemoteException;
    void scheduleSleeping(...) throws RemoteException;
    void scheduleResumeActivity(...) throws RemoteException;
    void scheduleSendResult(...) throws RemoteException;
    void scheduleLaunchActivity(...) throws RemoteException;
    void scheduleRelaunchActivity(...) throws RemoteException;
    void scheduleNewIntent(...) throws RemoteException;
    void scheduleDestroyActivity(...) throws RemoteException;
    void scheduleReceiver(...) throws RemoteException;
    ...
    void dumpService(...) throws RemoteException;
    void dumpProvider(...) throws RemoteException;
    ...
}

个人感觉:IActivityManager应该是更偏向于app进程向系统进程发出「启动活动、开启服务、绑定服务」这类请求,而IApplicationThread则更偏向于系统进程跟app进程说「ActivityonPause了,要调用什么什么生命周期方法了…」

流程总结
  1. 首先是在app进程,调用ActivitystartActivity(...),然后在InstrumentationexecStartActivity(...)会获取AMSapp进程的代理AMP,调用AMP的方法,就有了进程切换第一次:app进程 -> 系统进程的Binder线程池
  2. 调用AMP的方法,实际上是调用AMS在系统进程的startActivity(...),之后调用会走到ActivityStackSupervisor里,然后再走到ActivityStack,在ActivityStackstartPausingLocked(...)里,会拿到app进程在系统进程的binder代理ApplicationThreadProxy,调用它的schedulePauseActivity(...),真正的实现是在app进程的ApplicationThread,就有了进程切换第二次:系统进程 -> app进程Binder线程池
  3. 之后通过Handler,进行线程切换,为app进程Binder线程池 -> app进程主线程,在app进程主线程执行上一个ActivityonSaveInstanceState(Bundle outState)、onPause()生命周期方法调用(onStop()的调用不知道在哪,这篇文章就不分析了),也就是当前正在显示的Activity进行onPause操作,然后要启动的Activity才能进行onResume操作
  4. 等上一个ActivityonPause那些生命周期方法执行完,就又自动切换到系统进程,也就是进程切换第三次:app进程 -> 系统进程Binder线程池
  5. 之后调用又走到了ActivityStackSupervisor,然后在ActivityStackSupervisorrealStartActivityLocked(...)里,仍然是拿到app进程在系统进程的binder代理,即ApplicationThreadProxy,真正的实现是在app进程的ApplicationThread,调用它的scheduleLaunchActivity(...),就有了进程切换第四次:系统进程 -> app进程Binder线程池
  6. 然后通过Handler进行线程切换,为app进程Binder线程池 -> app进程主线程,然后在app进程的主线程创建Activity对象,尝试创建Application对象,调用Activityattach(...)方法,在attach(...)里会创建PhoneWindow对象,为PhoneWindow设置Activity的回调接口,调用ActivityonCreate(...),如果在onCreate(...)里进行setContentView(...),那么就会完成ActivityDecorView的创建和初始化,然后调用ActivityonStart()、onRestoreInstanceState()、onResume(),然后调用ActivitymakeVisible(...),在makeVisible(...)里,会将ActivityDecorView通过WindowManageraddView(...)(进行View的绘制等)正式添加到Window当中,这时候,DecorView才真正的完成了添加和显示的这两个过程,到这里Activity的视图才能被用户看到。

参考

《Android 开发艺术探索》

AndroidXRef Lollipop 5.0.0_r2

Android Launcher 启动 Activity 的工作过程_凶残的程序员

Android的Activity启动流程分析_流程图

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值