一张图表示Activity启动流程-- Activity启动流程详解

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq475703980/article/details/79701181

Activity启动流程比较复杂, 涉及的类及代码都很多, 本文侧重从整体流程描述这个过程,给出关键节点,尽量少的涉及代码细节。

啥也不说了,先上图。
在这里插入图片描述

在看本文的内容时, 可以参照此图片进行阅读。

Activity的启动过程主要会涉及五个进程:Launcher进程、System_server进程、当前的前台进程、待启动的Activity所在进程、Zygote进程, 在上图中已有所体现。

本文主要以Launcher启动APP的过程来分析。阅读过程可能会比较漫长, 如果只是想了解Activity启动的大致流程, 可以参流程图,跳过一些细节,但千万别放弃治疗。。。

基础介绍
1. Android的系统启动过程中会执行这样的一个逻辑:
>Zygote进程 --> System_Server进程(管理各种系统服务)--> 应用进程
2.Android进程间通讯Binder机制的简单理解

Android特有的进程间通信方式,可以简单的理解为三部分 Binder Client, Binder Server, Binder driver。进程A和进程B之间通讯, 如进程A想向进程B发起请求操作, 则进程A需要定义一个
Binder Client, 进程B定义一个Binder Server, client端向server发起请求操作这个过程会由Binder driver来协助执行。如果有数据返回, server端执行完后会返回一个Parcel数据。举一个简单的例子, 进程A想调用进程B的functionB()方法, 则进程A通过 已建立的Binder Client向进程B发起请求, 进程B的 Binder Server收到请求后,就会执行functionB()方法,如果functionB()方法是有返回值的, 则Binder Server会把这个值返回给进程A。如果进程B也想向进程A发起请求操作, 则需要再在进程B中建立一个Binder client, 进程A中建立一个Binder server, 然后进程B的 client向 进程A的 server发起请求。例如 进程B想请求进程A的 functionA()方法, 则需要进程 B 的client向进程A的 server发起请求。

本文的重点不是Binder机制, 如果不是很理解,可以自行查找下binder的相关资料,网上应该是多得用车都装不完的。。。下面进入正题。

一、开始请求启动Activity

启动Activity通常是在我们的Activity中启动另一个Activity, 或者在手机桌面点击App图标,就启动了我们的主Activity,但都是调用startActivity(intent)方法开始,下面介绍从Launcher启动我们的主Activity。

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    Intent intent = intentForPosition(position);
    startActivity(intent);
}

下面是方法调用链

Activity.startActivity() 
Activity.startActivityForResult()
Instrumentation.execStartActivty()
ActivityManagerNative.getDefault().startActivityAsUser() 

首先调用进Activity的startActivity()方法

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

然后在Activity中的startActivity方法体里调用了startActivity的重载方法,这里我们看一下其重载方法的实现:

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

由于在上一步骤中我们传递的Bunde对象为空,所以这里我们执行的是else分支的逻辑,所以这里调用了startActivityForResult方法,并且传递的参数为intent和-1.

额外收获:Android的源码真是太精妙了,代码复用到了极致, 这里调用startActivityForResult(), 由于我们本身没有传入requestCode, 这里系统传入了 -1,其实requestCode小于0都不会起作用的,可以实测一下, 具体原因我们接着分析。

我们接着往下看startActivityForResult方法的具体实现

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    if (mParent == null) {
        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) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

看到了吧, 这段代码里有一个判断

if (requestCode >= 0) {
	mStartedActivity = true;
}

这里就解释了 requestCode 小于0 确实是不起作用的, 上一段代码里, 我们主要看 mParent == null 这个分支就行了, mParent代表的是ActivityGroup, 最开始用来在一个界面中嵌入多个子Activity,但是在API13中已经废弃了, Google推荐我们用Fragment来代替ActivityGroup。然后调用mInstrumentation.execStartActivity()方法,简单解释下这几个参数:

this,为启动Activity的对象; 
contextThread,为Binder对象,是主进程的context对象; 
token,也是一个Binder对象,指向了服务端一个ActivityRecord对象; 
target,为启动的Activity; 
intent,启动的Intent对象; 
requestCode,请求码; 
options,参数;

接着看这个execStartActivity方法:

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

这个方法中主要调用ActivityManagerNative.getDefault().startActivity方法,这里要注意了,ActivityManagerNative是个什么东西呢, 跟进去看一下:

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

继续点进去往下看:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};

这里用到了Singleton, 这是个什么东西,点开看看。。。卧槽,原来是android自带的单例模式工具类, 以前都没发现。。。

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

接着我们刚刚的分析,注意这一行代码 IActivityManager am = asInterface(b);, 最终返回的是am, 点进去看看这个asInterface():

static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }

    return new ActivityManagerProxy(obj);
}

看着代码,熟悉Binder的同学是不是有点明白了, 这不就是Binder吗, 好了,要开始搞事情了, 肯定要跨进程通信了。我们刚刚说到通过Binder机制通信, 要在本地线程创建client,服务端进程创建Server。我们这里要启动一个Activity, 肯定要通知我们的System_Server进程吖, 这可是Android系统调度各种资源的核心进程。那就开始创建吧,于是在当前进程中创建一个本地代理ActivityManagerProxy,与System_server进程的 ActivityManagerService 进行交互, 这俩是一对儿。

可以看一下他们的源码, ActivityManagerProxy实现了IActivityManager接口, ActivityManagerService继承自ActivityManagerNative, ActivityManagerNative同样实现了IActivityManager接口,并且ActivityManagerNative是一个抽象类, 所以它的最终实现类就是ActivityManagerService。

我们接着刚刚的分析,调用ActivityManagerNative.getDefault().startActivity, 实际上就是调用ActivityManagerProxy.startActivity(), ActivityManagerProxy是ActivityManagerNative的一个内部类, 我们进去看一下:

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
        String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
    data.writeString(callingPackage);
    intent.writeToParcel(data, 0);
    data.writeString(resolvedType);
    data.writeStrongBinder(resultTo);
    data.writeString(resultWho);
    data.writeInt(requestCode);
    data.writeInt(startFlags);
    if (profilerInfo != null) {
        data.writeInt(1);
        profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    } else {
        data.writeInt(0);
    }
    if (options != null) {
        data.writeInt(1);
        options.writeToParcel(data, 0);
    } else {
        data.writeInt(0);
    }
    mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
    reply.readException();
    int result = reply.readInt();
    reply.recycle();
    data.recycle();
    return result;
}

注意到这一行代码: mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); 这就是开启Binder通信, 下面将进入System_Server进程, 当前进程的这个线程将挂起,等待Server端进程执行完毕。 我们进入ActivityManagerService去开看看这个被client端调用的startActivity()方法。

二、System_Server进程接收到启动Activity的请求

先贴一下接下来的方法调用链

ActivityManagerService.startActivity() 
ActvityiManagerService.startActivityAsUser() 
ActivityStackSupervisor.startActivityMayWait() 
ActivityStackSupervisor.startActivityLocked() 
ActivityStackSupervisor.startActivityUncheckedLocked() 
ActivityStackSupervisor.startActivityLocked() 
ActivityStackSupervisor.resumeTopActivitiesLocked() 
ActivityStackSupervisor.resumeTopActivityInnerLocked() 

不要慌, 兄弟,不要慌, 放轻松, 我们一个一个往下看, 首先看一下ActivityManagerService.startActivity()这个方法的实现:

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

啥都没有,就调了一个方法, 接着往下看:

@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);
    // TODO: Switch to user app stacks here.
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);
}

这里进行了一些关于userid的逻辑判断,然后就调用mStackSupervisor.startActivityMayWait方法:

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, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
        ...

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

这个方法中执行了启动Activity的一些其他逻辑判断,在经过判断逻辑之后调用startActivityLocked方法:

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 ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        ActivityContainer container, TaskRecord inTask) {
   		 int err = ActivityManager.START_SUCCESS;

  		  ...
		
		ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, this, container, options);

		  ...

 	   err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);

        ...
        return err;
}

这个方法中构造了ActivityManagerService端的Activity对象–>ActivityRecord, 我们看一下ActivityRecord这个类的源码注释

/**
 * An entry in the history stack, representing an activity.
 */
final class ActivityRecord {

翻译一下:存在历史栈的一个实例,代表一个Activity。这就是ActivityManagerService中代表Activity的实例, 我们接着看调用的startActivityUncheckedLocked方法:

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
        boolean doResume, Bundle options, TaskRecord inTask) {
    ...
    ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
    targetStack.mLastPausedActivity = null;
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    if (!launchTaskBehind) {
        // Don't set focus on an activity that's going to the back.
        mService.setFocusedActivityLocked(r, "startedActivity");
    }
    return ActivityManager.START_SUCCESS;
}

startActivityUncheckedLocked方法中对Activity的启动模式和对应的任务栈进行了判断和处理,然后调用了startActivityLocked的重载方法:

final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options) {
    ...

	if (!newTask) {
        // If starting in an existing task, find where that is...
	...

	}

	...

    if (doResume) {
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}

这个方法里对是否是一个新的任务栈Task进行了相关处理,保存在windowManager服务中, 然后调用resumeTopActivitiesLocked方法:

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
        Bundle targetOptions) {
    if (targetStack == null) {
        targetStack = mFocusedStack;
    }
    // Do targetStack first.
    boolean result = false;
    if (isFrontStack(targetStack)) {
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }

    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (stack == targetStack) {
                // Already started above.
                continue;
            }
            if (isFrontStack(stack)) {
                stack.resumeTopActivityLocked(null);
            }
        }
    }
    return result;
}

经过循环逻辑判断之后,最终调用了resumeTopActivityLocked方法:

final boolean resumeTopActivityLocked(ActivityRecord prev) {
    return resumeTopActivityLocked(prev, null);
}

继续跟进代码:

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

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
            mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
            mService.updateSleepIfNeededLocked();
        }
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    return result;

继续调用resumeTopActivityInnerLocked方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

    ...
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    }        ...
    return true;
}

经过一系列处理逻辑之后最终调用了startPausingLocked方法,这个方法作用就是让系统中栈中的Activity执行onPause方法。

三、执行栈顶Activity的onPause方法

方法调用链:

ActivityStack.startPausingLocked() 
IApplicationThread.schudulePauseActivity() 
ActivityThread.sendMessage() 
ActivityThread.H.sendMessage(); 
ActivityThread.H.handleMessage() 
ActivityThread.handlePauseActivity() 
ActivityThread.performPauseActivity() 
Activity.performPause() 
Activity.onPause() 
ActivityManagerNative.getDefault().activityPaused(token) 
ActivityManagerService.activityPaused() 
ActivityStack.activityPausedLocked() 
ActivityStack.completePauseLocked() 
ActivityStack.resumeTopActivitiesLocked() 
ActivityStack.resumeTopActivityLocked() 
ActivityStack.resumeTopActivityInnerLocked() 
ActivityStack.startSpecificActivityLocked()

不要被这么多方法吓到了, 主线已经比较清楚了, 从第一个方法看起:

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
        boolean dontWait) {
    ...
    if (prev.app != null && prev.app.thread != null) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
            EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                    prev.userId, System.identityHashCode(prev),
                    prev.shortComponentName);
            mService.updateUsageStats(prev, false);
            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                    userLeaving, prev.configChangeFlags, dontWait);
        } catch (Exception e) {
            // Ignore exception, if process died other code will cleanup.
            Slog.w(TAG, "Exception thrown during pause", e);
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }
    ...
}

注意这一行代码:pre.app.thread.schedulePauseActivity(),这里的thread是一个IApplicationThread类型的对象,实现这一接口的类只有ApplicationThreadNative,并且是一个抽象类还继承了Binder, 所以这是一个Binder对象,然后继承ApplicationThreadNative的有两个类, 分别是 ActivityThread中的内部类ApplicationThread, 以及ApplicationThreadNative中的内部类 ApplicationThreadProxy,所以他们也都是Binder对象, 看见Binder, 我们就知道,肯定要搞事情了, 要跨进程传输了。有没有似曾相识的感觉, 前面我们介绍ActivityManagerService时, 也是同样的套路。

对比一下:

IActivityManager接口
	ActivityManagerNative 		 唯一实现类, 抽象类
		ActivityManagerService   binder的服务端
		ActivityManagerProxy     binder的客户端, ActivityManagerNative的内部类,

IApplicationThread接口
	ApplicationThreadNative 	 唯一实现类, 抽象类
		ApplicationThread        binder服务端
		ApplicationThreadProxy   binder客户端, ApplicationThreadNative的内部类

接着刚刚的代码看,pre.app.thread.schedulePauseActivity(), 这一行代码,schedulePauseActivity() 从这个方法的名我们大致可以看出, 这是一个执行onPause()的方法, 可是目前还在System_server进程中啊, 所以我们要通知当前的前台应用进程,告诉它:你的Activity该执行onPause了。由于我们目的是要调用到当前前台进程的方法, 所以这里我们在当前进程即 System_Server进程建立Binder client端,即ApplicationThreadProxy, 然后向Binder server端, 即前台进程的ApplicationThread 发起binder通信。 这里如果不是很理解的话, 可以先记忆下来, 这就是Binder通信的套路。

所以这里pre.app.thread.schedulePauseActivity()实际上就是调用ActivityManagerProxy.schedulePauseActivity()方法, 我们进去看一下

public final void schedulePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    data.writeInt(finished ? 1 : 0);
    data.writeInt(userLeaving ? 1 :0);
    data.writeInt(configChanges);
    data.writeInt(dontReport ? 1 : 0);
    mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}

可以看到, 这里调用了mRemote.transac(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,data, null,IBinder.FLAG_ONEWAY);这里的mRemote就是一个Binder对象, 是一个服务端在本地的binder代理对象, 调用了transac()方法, 发起了Binder通信。 接下来, 我们去服务端的ApplicationThread这个类看看:

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

这里发送了一个消息, 点进去:

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;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

最终调用了mH的sendMessage方法,mH是在ActivityThread中的一个Handler对象,主要处理SystemServer进程的消息,我们看一下其handleMessge方法的实现:

public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            ...
            case PAUSE_ACTIVITY_FINISHING:
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
                        (msg.arg1&1) != 0);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
            ...
}	

发现其调用了handlePauseActivity方法:

private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(token, finished, r.isPreHoneycomb());

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
        mSomeActivitiesChanged = true;
    }
}

然后在方法体内部通过调用performPauseActivity方法来实现对栈顶Activity的onPause生命周期方法的回调,可以具体看一下他的实现:

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) {
    ...
    mInstrumentation.callActivityOnPause(r.activity);
    ...

    return !r.activity.mFinished && saveState ? r.state : null;
}

这样回到了mInstrumentation的callActivityOnPuase方法:

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

看见了吧, 看见了吧,进入Activity的身体了, 点进去performPause()看看:

final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause();
    mCalled = false;
    onPause();
    mResumed = false;
    if (!mCalled && getApplicationInfo().targetSdkVersion
            >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPause()");
    }
    mResumed = false;
}

哈哈哈哈哈, 终于看到onPause()方法了!

特别注意: 面试的时候有时会问到类似的问题, Activity启动另一个Activity, onPause()和 onCreate()谁先执行, 从这里我们得知, 是onPause先得到执行。

回到我们刚刚的handlePauseActivity方法, 执行完上述代码后, 还执行了另一行重要代码:ActivityManagerNative.getDefault().activityPaused(token); 这个的作用就是告诉System_Server进程, 我前台进程已执行完onPause()方法了, 你可以继续往下执行了。 这里同样是跨进程binder通信, 通过前面的分析, 我们知道最终会调用到System_server进程中的ActivityManagerService的activityPaused方法:

@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

可以发现,该方法内部会调用ActivityStack的activityPausedLocked方法,好吧,继续看一下activityPausedLocked方法的实现:

private void completePauseLocked(boolean resumeNext) {
    ...

    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
        } else {
            mStackSupervisor.checkReadyForSleepLocked();
            ActivityRecord top = topStack.topRunningActivityLocked(null);
            if (top == null || (prev != null && top != prev)) {
                // If there are no more activities available to run,
                // do resume anyway to start something.  Also if the top
                // activity on the stack is not the just paused activity,
                // we need to go ahead and resume it to ensure we complete
                // an in-flight app switch.
                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
            }
        }
    }
    ...
}

经过了一系列的逻辑之后,又调用了resumeTopActivitiesLocked方法,又回到了第二步中解析的方法中了,这样经过

resumeTopActivitiesLocked –>

ActivityStack.resumeTopActivityLocked() –>

resumeTopActivityInnerLocked() –>

startSpecificActivityLocked()

我们看一下startSpecificActivityLocked的具体实现:

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.task.stack.setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            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.
    }

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

可以发现在这个方法中,首先会判断一下需要启动的Activity所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。
这样关于启动Activity时的第三步骤就已经执行完成了,这里主要是实现了对栈顶Activity执行onPause
方法,而这个方法首先判断需要启动的Activity所属的进程是否已经启动,若已经启动则直接调用启动Activity的方法,否则将先启动Activity的应用进程,然后在启动该Activity。

四、启动Activity所属进程

方法调用链:

ActivityManagerService.startProcessLocked() 
Process.start() 
ActivityThread.main() 
ActivityThread.attach() 
ActivityManagerNative.getDefault().attachApplication() 
ActivityManagerService.attachApplication() 

首先看一下startProcessLocked()方法的具体实现:

private final void startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr) {
    startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
            null /* entryPoint */, null /* entryPointArgs */);
}

private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ...
        boolean isActivityProcess = (entryPoint == null);
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);
        checkTime(startTime, "startProcess: asking zygote to start proc");
        Process.ProcessStartResult startResult = Process.start(entryPoint,
                app.processName, uid, uid, gids, debugFlags, mountExternal,
                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                app.info.dataDir, entryPointArgs);
        checkTime(startTime, "startProcess: returned from zygote!");
        ...
}

从上述方法考单,经过一系列的初始化操作之后调用了Process.start方法,并且传入了启动的类名“android.app.ActivityThread”, 接着看start:

public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}

这里调用了startViaZygote()方法:

private static ProcessStartResult startViaZygote(final String processClass,
                              final String niceName,
                              final int uid, final int gid,
                              final int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] extraArgs)
                              throws ZygoteStartFailedEx {
    synchronized(Process.class) {
        ...

        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

这里最终调用了zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); 进入这个zygoteSendArgsAndGetResult()方法, 发现并没有太多操作,就是一些读写流, 最后反回了一个ProcessStartResult对象,见名知意,返回的是一个进程开启结果对象。 所以我们进入openZygoteSocketIfNeeded(abi), 具体操作肯定在这里:

/** 
* Tries to open socket to Zygote process if not already open. If 
* already open, does nothing.  May block and retry. 
*/  
private static void openZygoteSocketIfNeeded()  
        throws ZygoteStartFailedEx {  

    int retryCount;  

    if (sPreviousZygoteOpenFailed) {  
        /* 
        * If we've failed before, expect that we'll fail again and 
        * don't pause for retries. 
        */  
        retryCount = 0;  
    } else {  
        retryCount = 10;  
    }  
  
    /* 
    * See bug #811181: Sometimes runtime can make it up before zygote. 
    * Really, we'd like to do something better to avoid this condition, 
    * but for now just wait a bit... 
    */  
    for (int retry = 0  
        ; (sZygoteSocket == null) && (retry < (retryCount + 1))  
        ; retry++ ) {  

            if (retry > 0) {  
                try {  
                    Log.i("Zygote", "Zygote not up yet, sleeping...");  
                    Thread.sleep(ZYGOTE_RETRY_MILLIS);  
                } catch (InterruptedException ex) {  
                    // should never happen  
                }  
            }  

            try {  
                sZygoteSocket = new LocalSocket();  
                sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,  
                    LocalSocketAddress.Namespace.RESERVED));  

                sZygoteInputStream  
                    = new DataInputStream(sZygoteSocket.getInputStream());  

                sZygoteWriter =  
                    new BufferedWriter(  
                    new OutputStreamWriter(  
                    sZygoteSocket.getOutputStream()),  
                    256);  

                Log.i("Zygote", "Process: zygote socket opened");  

                sPreviousZygoteOpenFailed = false;  
                break;  
            } catch (IOException ex) {  
                ......  
            }  
    }  

    ......  
}  

在这里面, 我们看到 sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, LocalSocketAddress.Namespace.RESERVED)); 这里实际上就是通过socket流与 Zygote进程进行通信, 通知Zygote创建一个新的进程。这里根据Android界人尽皆知的大神 老罗的源码分析, 最终这个Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit类在runSelectLoopMode函数侦听到。 【注意】如果对这个过程不想细看,可以跳过,直接进入下一个缓解。这里博主想进入到Zygote的身体里面,去解读一些不为人知的奥秘(微笑脸):

public class ZygoteInit {  
......  

/** 
* Runs the zygote process's select loop. Accepts new connections as 
* they happen, and reads commands from connections one spawn-request's 
* worth at a time. 
* 
* @throws MethodAndArgsCaller in a child process when a main() should 
* be executed. 
*/  
private static void runSelectLoopMode() throws MethodAndArgsCaller {  
    ArrayList<FileDescriptor> fds = new ArrayList();  
    ArrayList<ZygoteConnection> peers = new ArrayList();  
    FileDescriptor[] fdArray = new FileDescriptor[4];  

    fds.add(sServerSocket.getFileDescriptor());  
    peers.add(null);  

    int loopCount = GC_LOOP_COUNT;  
    while (true) {  
        int index;  
        /* 
        * Call gc() before we block in select(). 
        * It's work that has to be done anyway, and it's better 
        * to avoid making every child do it.  It will also 
        * madvise() any free memory as a side-effect. 
        * 
        * Don't call it every time, because walking the entire 
        * heap is a lot of overhead to free a few hundred bytes. 
        */  
        if (loopCount <= 0) {  
            gc();  
            loopCount = GC_LOOP_COUNT;  
        } else {  
            loopCount--;  
        }  


        try {  
            fdArray = fds.toArray(fdArray);  
            index = selectReadable(fdArray);  
        } catch (IOException ex) {  
            throw new RuntimeException("Error in select()", ex);  
        }  

        if (index < 0) {  
            throw new RuntimeException("Error in select()");  
        } else if (index == 0) {  
            ZygoteConnection newPeer = acceptCommandPeer();  
            peers.add(newPeer);  
            fds.add(newPeer.getFileDesciptor());  
        } else {  
            boolean done;  
            done = peers.get(index).runOnce();  

            if (done) {  
                peers.remove(index);  
                fds.remove(index);  
            }  
        }  
    }  
}  

......  	
}  

分析上述代码, 将数据通过Socket接口发送出去后,就会执行这一行:

done = peers.get(index).runOnce();

这里从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce函数进一步处理了。
Step 6. ZygoteConnection.runOnce
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:

class ZygoteConnection {  
	......  

    private void handleChildProc(Arguments parsedArgs,  
            FileDescriptor[] descriptors, PrintStream newStderr)  
            throws ZygoteInit.MethodAndArgsCaller {  
        ......  
  
        if (parsedArgs.runtimeInit) {  
            RuntimeInit.zygoteInit(parsedArgs.remainingArgs);  
        } else {  
            ......  
        }  
    }  
  
    ......  
}  

继续看RuntimeInit.zygoteInit:

public static final void zygoteInit(String[] argv)  
        throws ZygoteInit.MethodAndArgsCaller {  
    // TODO: Doing this here works, but it seems kind of arbitrary. Find  
    // a better place. The goal is to set it up for applications, but not  
    // tools like am.  
    System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));  
    System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));  

    commonInit();  
    zygoteInitNative();  

    int curArg = 0;  
    for ( /* curArg */ ; curArg < argv.length; curArg++) {  
        String arg = argv[curArg];  

        if (arg.equals("--")) {  
            curArg++;  
            break;  
        } else if (!arg.startsWith("--")) {  
            break;  
        } else if (arg.startsWith("--nice-name=")) {  
            String niceName = arg.substring(arg.indexOf('=') + 1);  
            Process.setArgV0(niceName);  
        }  
    }  

    if (curArg == argv.length) {  
        Slog.e(TAG, "Missing classname argument to RuntimeInit!");  
        // let the process exit  
        return;  
    }  

    // Remaining arguments are passed to the start class's static main  

    String startClass = argv[curArg++];  
    String[] startArgs = new String[argv.length - curArg];  

    System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);  
    invokeStaticMain(startClass, startArgs);  
}  

这里有两个关键的函数调用,一个是zygoteInitNative函数调用,一个是invokeStaticMain函数调用,前者就是执行Binder驱动程序初始化的相关工作了,正是由于执行了这个工作,才使得进程中的Binder对象能够顺利地进行Binder进程间通信,而后一个函数调用,就是执行进程的入口函数,这里就是执行startClass类的main函数了,而这个startClass即是我们在Step 1中传进来的"android.app.ActivityThread"值,表示要执行android.app.ActivityThread类的main函数。

卧槽, 是不是更加明白为啥ActivityThread叫主线程了吧, 一个进程的java启动入口, 就是从这里开始的。

好了, 这些我们真正的进入了我们待启动Activity的进程身体里面了, 看一下ActivityThread的main方法:

public static void main(String[] args) {
    ...
    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

主要执行了一些初始化的逻辑,并且创建了一个UI线程消息队列,这也就是为什么我们可以在主线程中随意的创建Handler而不会报错的原因, 这也是为啥我们在子线程创建消息队列的话,要调用Looper.prepare()方法了。

然后执行了ActivityThread的attach方法,这里我们看一下attach方法:

private void attach(boolean system) {
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
...
}

又是老套路, 前面我们已经分析过了, 这里会通过Binder调用System_server进程的ActivityManagerService的attachApplication(), 继续看:

public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

发现其回调了attachApplicationLocked方法:

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {

    ...
    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    ...

    return true;
}

该方法执行了一系列的初始化操作, 调用了 mStackSupervisor.attachApplicationLocked(app)。

为什么我们待启动Activity的进程已经启动了, 还要进入System_server进程呢。 因为System_server进程管理了很多系统资源的调度, 所以我们真正启动我们的Activity之前, 还要System_server进程中做一些操作, 当一切准备工作做好了, 就会通知应用进程, 你可以真正执行Activity的启动了, 下面, 我们接着分析。

五、启动Activity

调用方法链:

ActivityStackSupervisor.attachApplicationLocked() 
ActivityStackSupervisor.realStartActivityLocked() 
IApplicationThread.scheduleLauncherActivity() 
ActivityThread.sendMessage() 
ActivityThread.H.sendMessage() 
ActivityThread.H.handleMessage() 
ActivityThread.handleLauncherActivity() 
ActivityThread.performLauncherActivity() 
Instrumentation.callActivityOnCreate() 
Activity.onCreate() 
ActivityThread.handleResumeActivity() 
ActivityThread.performResumeActivity() 
Activity.performResume() 
Instrumentation.callActivityOnResume() 
Activity.onResume() 
ActivityManagerNative.getDefault().activityResumed(token) 

接着上面的分析, 先来看看attachApplicationLocked:

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFrontStack(stack)) {
                continue;
            }
            ActivityRecord hr = stack.topRunningActivityLocked(null);
            if (hr != null) {
                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                        && processName.equals(hr.processName)) {
                    try {
                        if (realStartActivityLocked(hr, app, true, true)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                              + hr.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0);
    }
    return didSomething;

其内部调用了realStartActivityLocked方法:

final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {

    ...
        app.forceProcessStateUpTo(mService.mTopProcessState);
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
    ...
    return true;
}

又来了, app.thread.scheduleLaunchActivity(), 前面已分析过, 又是Binder, 这里最终调用的是我们待启动Activity进程中的ActivityThread中的scheduleLauncherActivity, 好了, 我们再次进入待启动Activity进程的身体:

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

        ActivityClientRecord r = new ActivityClientRecord();

        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.referrer = referrer;
        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;

        r.overrideConfig = overrideConfig;
        updatePendingConfiguration(curConfig);

        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

还是之前的逻辑,ActivityThread接收到System_Server进程的消息之后会通过其内部的Handler对象分发消息,经过一系列的分发之后最终调用了ActivityThread的handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);


    }
    ...
}

这里调用了performLauncherActivity,看名字应该就是执行Activity的启动操作了:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...

	Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        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);
        }
    }
    ...

    activity.mCalled = false;
    if (r.isPersistable()) {
       mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
       mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    ...
    if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
    ...
    return activity;
}

可以发现这里我们需要的Activity对象终于是创建出来了,而且他是以反射的机制创建的,这里也体现了Android代码复用的精妙,这一整套代码都系系统的, 但是具体的Activity类名,系统一开始不知道的,这里传进来类名, 通过反射即可擦混个建对象。

然后调用了mInstrumentation.callActivityOnCreate():

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

然后activity.performCreate():

final void performCreate(Bundle icicle) {
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

哈哈哈哈哈, 同志们,看见了吧, 生命周期方法onCreate()在这里被调用了 。

按耐住激动的心情, 回到我们的performLaunchActivity方法中,其在调用了mInstrumentation.callActivityOnCreate方法之后又调用了activity.performStart()方法,看起来是调用onStart()方法的, 进去看一下:

final void performStart() {
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    mFragments.noteStateNotSaved();
    mCalled = false;
    mFragments.execPendingActions();
    mInstrumentation.callActivityOnStart(this);
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onStart()");
    }
    mFragments.dispatchStart();
    mFragments.reportLoaderStart();
    mActivityTransitionState.enterReady(this);
}

又是通过Instrumentation调用callActivityOnStart方法:

public void callActivityOnStart(Activity activity) {
    activity.onStart();
}

onStart方法也出现了~~~

再次回到刚刚的handleLaunchActivity方法,在调用完performLaunchActivity方法之后,其又调用了handleResumeActivity方法:

final void handleResumeActivity(IBinder token,
        boolean clearHide, boolean isForward, boolean reallyResume) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    // TODO Push resumeArgs into the activity for consideration
    ActivityClientRecord r = performResumeActivity(token, clearHide);

    if (r != null) {
	
	...
        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            if (r.newConfig != null) {
                r.tmpConfig.setTo(r.newConfig);
                if (r.overrideConfig != null) {
                    r.tmpConfig.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                        + r.activityInfo.name + " with newConfig " + r.tmpConfig);
                performConfigurationChanged(r.activity, r.tmpConfig);
                freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
                r.newConfig = null;
            }
            
           
        }

    	...

        // Tell the activity manager we have resumed.
        if (reallyResume) {
            try {
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
            }
        }

    } else {
        // If an exception was thrown when trying to resume, then
        // just end this activity.
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(token, Activity.RESULT_CANCELED, null, false);
        } catch (RemoteException ex) {
        }
    }
}

resumeActivity的逻辑调用到了performResumeActivity()方法,还看到了performConfigurationChanged(), 我们来重点关注下performResumeActivity:

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

都是老套路, 接着看 callActivityOnResume:

public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    activity.onResume();

    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                am.match(activity, activity, activity.getIntent());
            }
        }
    }
}

onResume方法。。。它出现了~~~

这时候我们的界面应该已经展示出来了,我们的Activity应该已经启动,但是完,我们的生命周期方法还没走完:Activity a 启动 Activity b 会触发的生命周期方法:a的onPause方法和onStop方法,b的onCreate onStart方法,onResume方法, 现在, 就差 a的 onStop了

六、栈顶Activity执行onStop方法

继续贴方法链:

Looper.myQueue().addIdleHandler(new Idler()) 
Idler.queueIdle() 
ActivityManagerNative.getDefault().activityIdle() 
ActivityManagerService.activityIdle() 
ActivityStackSupervisor.activityIdleInternalLocked() 
ActivityStack.stopActivityLocked() 
IApplicationThread.scheduleStopActivity() 
ActivityThread.scheduleStopActivity() 
ActivityThread.sendMessage() 
ActivityThread.H.sendMessage() 
ActivityThread.H.handleMessage() 
ActivityThread.handleStopActivity() 
ActivityThread.performStopActivityInner() 
ActivityThread.callCallActivityOnSaveInstanceState() 
Instrumentation.callActivityOnSaveInstanceState() 
Activity.performSaveInstanceState() 
Activity.onSaveInstanceState() 
Activity.performStop() 
Instrumentation.callActivityOnStop() 
Activity.onStop() 

回到我们的handleResumeActivity方法,在方法体最后有这样的一代码:

Looper.myQueue().addIdleHandler(new Idler());

点进去看一下:

private class Idler implements MessageQueue.IdleHandler {
    @Override
    public final boolean queueIdle() {
        ActivityClientRecord a = mNewActivities;
        boolean stopProfiling = false;
        if (mBoundApplication != null && mProfiler.profileFd != null
                && mProfiler.autoStopProfiler) {
            stopProfiling = true;
        }
        if (a != null) {
            mNewActivities = null;
            IActivityManager am = ActivityManagerNative.getDefault();
            ActivityClientRecord prev;
            do {
                if (localLOGV) Slog.v(
                    TAG, "Reporting idle of " + a +
                    " finished=" +
                    (a.activity != null && a.activity.mFinished));
                if (a.activity != null && !a.activity.mFinished) {
                    try {
                        am.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    } catch (RemoteException ex) {
                        // Ignore
                    }
                }
                prev = a;
                a = a.nextIdle;
                prev.nextIdle = null;
            } while (a != null);
        }
        if (stopProfiling) {
            mProfiler.stopProfiling();
        }
        ensureJitEnabled();
        return false;
    }
}

这样当Messagequeue执行add方法之后就会回调其queueIdle()方法,我们可以看到在方法体中其调用了ActivityManagerNative.getDefault().activityIdle(),好吧,熟悉了Binder机制以后我们知道这段代码会执行到ActivityManagerService的activityIdle方法:

public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
    final long origId = Binder.clearCallingIdentity();
    synchronized (this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            ActivityRecord r =
                    mStackSupervisor.activityIdleInternalLocked(token, false, config);
            if (stopProfiling) {
                if ((mProfileProc == r.app) && (mProfileFd != null)) {
                    try {
                        mProfileFd.close();
                    } catch (IOException e) {
                    }
                    clearProfilerLocked();
                }
            }
        }
    }
    Binder.restoreCallingIdentity(origId);
}

然后在activityIdle方法中又调用了ActivityStackSupervisor.activityIdleInternalLocked方法:

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
        Configuration config) {
    ...

    // Stop any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NS; i++) {
        r = stops.get(i);
        final ActivityStack stack = r.task.stack;
        if (stack != null) {
            if (r.finishing) {
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
            } else {
                stack.stopActivityLocked(r);
            }
        }
    }

    ...

    return r;
}

可以发现在其中又调用了ActivityStack.stopActivityLocked方法:

final void stopActivityLocked(ActivityRecord r) {
    if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
    if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
            || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
        ...
            r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
         ...
    }
}

好吧,又是相同的逻辑通过调用IApplicationThread.scheduleStopActivity(), 实际上是使用Binder,通过最终调用了Launcher进程(如果是从Launcher启动的APP)的ActivityThread.scheduleStopActivity()方法。。。。

public final void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) {
       sendMessage(
            showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
            token, 0, configChanges);
    }

然后执行sendMessage方法,最终执行H(Handler)的sendMessage方法,并被H的handleMessge方法接收执行handleStopActivity方法:

private void handleStopActivity(IBinder token, boolean show, int configChanges) {
    ...
    performStopActivityInner(r, info, show, true);
    ...
}

然后我们看一下performStopActivityInner的实现逻辑:

private void performStopActivityInner(ActivityClientRecord r,
        StopInfo info, boolean keepShown, boolean saveState) {
        ...
        // Next have the activity save its current state and managed dialogs...
        if (!r.activity.mFinished && saveState) {
            if (r.state == null) {
                callCallActivityOnSaveInstanceState(r);
            }
        }

        if (!keepShown) {
            try {
                // Now we are idle.
                r.activity.performStop();
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                            "Unable to stop activity "
                            + r.intent.getComponent().toShortString()
                            + ": " + e.toString(), e);
                }
            }
            r.stopped = true;
        }
    }
}

看样子在这个方法中执行了两个逻辑,一个是执行Activity的onSaveInstance方法一个是执行Activity的onStop方法

注意: 我们看到这里 调用callCallActivityOnSaveInstanceState® 方法前进行了一些判断, 主要是判断Activity是被正常终止的, 如果是, 则不会调用onSaveInstanceState()方法, 如果是被异常终止的, 比如进程被杀掉等, 才会调用onSaveInstanceState()。

接着分析, 先看一下callCallActivityOnSaveInstanceState的执行逻辑:

private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
    r.state = new Bundle();
    r.state.setAllowFds(false);
    if (r.isPersistable()) {
        r.persistentState = new PersistableBundle();
        mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
                r.persistentState);
    } else {
        mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
    }
}

老套路,又是通过Instrumentation来执行, 最终调用了onSaveInstanceState():

public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
        PersistableBundle outPersistentState) {
    activity.performSaveInstanceState(outState, outPersistentState);
}

final void performSaveInstanceState(Bundle outState) {
    onSaveInstanceState(outState);
    saveManagedDialogs(outState);
    mActivityTransitionState.saveState(outState);
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
}

然后我们看一下performStopActivityInner中调用到的Activity方法的performStop方法:

final void performStop() {
    mDoReportFullyDrawn = false;
    mFragments.doLoaderStop(mChangingConfigurations /*retain*/);

    if (!mStopped) {
        if (mWindow != null) {
            mWindow.closeAllPanels();
        }

        if (mToken != null && mParent == null) {
            WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
        }

        mFragments.dispatchStop();

        mCalled = false;
        mInstrumentation.callActivityOnStop(this);
        if (!mCalled) {
            throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onStop()");
        }

        synchronized (mManagedCursors) {
            final int N = mManagedCursors.size();
            for (int i=0; i<N; i++) {
                ManagedCursor mc = mManagedCursors.get(i);
                if (!mc.mReleased) {
                    mc.mCursor.deactivate();
                    mc.mReleased = true;
                }
            }
        }

        mStopped = true;
    }
    mResumed = false;
}

还是通过Instrumentation来实现的,调用了它的callActivityOnStop方法:

public void callActivityOnStop(Activity activity) {
    activity.onStop();
}

最终,我们看到调用了onStop()方法。

哎呀, 终于结束了。。。眼睛都花了。。。

总结:

Activity的启动流程一般是通过调用startActivity或者是startActivityForResult来开始的

startActivity内部也是通过调用startActivityForResult来启动Activity,只不过传递的requestCode小于0

Activity的启动流程涉及到多个进程之间的通讯这里主要是ActivityThread与ActivityManagerService之间的通讯

ActivityThread向ActivityManagerService传递进程间消息通过ActivityManagerNative,ActivityManagerService向ActivityThread进程间传递消息通过IApplicationThread。

ActivityManagerService接收到应用进程创建Activity的请求之后会执行初始化操作,解析启动模式,保存请求信息等一系列操作。

ActivityManagerService保存完请求信息之后会将当前系统栈顶的Activity执行onPause操作,并且IApplication进程间通讯告诉应用程序继承执行当前栈顶的Activity的onPause方法;

ActivityThread接收到SystemServer的消息之后会统一交个自身定义的Handler对象处理分发;

ActivityThread执行完栈顶的Activity的onPause方法之后会通过ActivityManagerNative执行进程间通讯告诉ActivityManagerService,栈顶Actiity已经执行完成onPause方法,继续执行后续操作;

ActivityManagerService会继续执行启动Activity的逻辑,这时候会判断需要启动的Activity所属的应用进程是否已经启动,若没有启动则首先会启动这个Activity的应用程序进程;

ActivityManagerService会通过socket与Zygote继承通讯,并告知Zygote进程fork出一个新的应用程序进程,然后执行ActivityThread的mani方法;

在ActivityThead.main方法中执行初始化操作,初始化主线程异步消息,然后通知ActivityManagerService执行进程初始化操作;

ActivityManagerService会在执行初始化操作的同时检测当前进程是否有需要创建的Activity对象,若有的话,则执行创建操作;

ActivityManagerService将执行创建Activity的通知告知ActivityThread,然后通过反射机制创建出Activity对象,并执行Activity的onCreate方法,onStart方法,onResume方法;

ActivityThread执行完成onResume方法之后告知ActivityManagerService onResume执行完成,开始执行栈顶Activity的onStop方法;

ActivityManagerService开始执行栈顶的onStop方法并告知ActivityThread;

ActivityThread执行真正的onStop方法;

参考博文:

《Android开发艺术探索》
https://blog.csdn.net/luoshengyang/article/details/6747696
https://www.jianshu.com/p/dbea4645cbc7
https://blog.csdn.net/qq_23547831/article/details/51224992
展开阅读全文

没有更多推荐了,返回首页