Android 组件系列 -- Activity 启动流程(9.0)

在学习完Android应用程序启动过程源代码分析,针对最新Android9.0的代码,以相应的顺序再次学习。在9.0的版本中对于Activity的启动流程上并没有太大的变化,但是在代码层面,改动的却很多。


流程概览

以Launcher启动APP为例:

  1. Launcher通过Binder建立Launcher所在进程与system_server进程(ActivityManagerService所在进程)的通信,通知ActivityManagerService即将要启动一个Activity
  2. ActivityManagerService通过Binder让Launcher进入pause状态
  3. Launcher进入pause状态后,随后ActivityManagerService创建一个进程(将要打开的应用进程)并启动ActivityThread(应用的UI线程)
  4. ActivityThread通过Binder将ApplicationThread类型的Binder对象传递给ActivityManagerService,方便ActivityManagerService后续与其的通信
  5. 准备工作完成后,ActivityManagerService通知ActivityThread启动Activity
  6. ActivityThread调度执行Activity的生命周期方法,完成启动Activity的工作

从Activity到Instrumentation的过程

其实不论是从Launcher中启动Activity,还是应用内启动Activity,最终都会调用到Activity的startActivityForResult :

public class Activity extends ...{

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
    
	@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            ...
        } 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(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

	public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            ...
        } else {
            ...
        }
    }
}

最终走到了startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options)方法中。其中:
mParent :所代表的其实是当前Activity的父,这是Activity嵌套Activity的设计,现在当然很少用了,这里mParent为null。
mMainThread.getApplicationThread() : 其实获取的是当前所在应用的ApplicationThread实例,需要知道的是class ApplicationThread extends IApplicationThread.Stub,从代码继承上一看便知道,ApplicationThread其实就是基于Binder来进行IPC通信的类。
mToken:它是一个Binder对象的远程接口,其实可以看做是Activity的键,事实上,这也是在代码中的它的定位,通过mToken来定位它所代表的Activity。
intent, requestCode, options: intent就是传递进去的intent,requestCode,options都是为startActivityForResult所传的参数,此处都没有用处,可以忽略。


从Instrumentation进入FrameWork,与AMS/PMS等服务打交道

与老版本不同的是,在Instrumentation.execStartActivity方法中,并没有ActivityManagerNative类的身影,而是直接使用ActivityManager.getService()获取到AMS(ActivityManagerService)的实例,到这一步其实已经不在当前应用中了,已经通过Binder进入到了framework层了。

//---Instrumentation
public class Instrumentation {
	public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        ...
    }
}
在ActivityManagerService中进入ActivityStarter: Activity的启动管理类
//---ActivityManagerService
public class ActivityManagerService extends IActivityManager.Stub implements ...{
	@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                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 bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)//这个方法需要注意下
                .execute();
    }
}
在最后一步mActivityStartController.obtainStarter,发现了一个新的类ActivityStarter:很明显这个类用来管理Activity的启动。
//---ActivityStarter  
class ActivityStarter {
	//在ActivityManagerService最后一步startActivityAsUser中,该方法被调用
	ActivityStarter setMayWait(int userId) {
        mRequest.mayWait = true;
        mRequest.userId = userId;
        return this;
    }

	int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
               ...
            }
        } finally {
            onExecutionComplete();
        }
    }
	
	private 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 globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
        ...
        // Collect information about the target of the Intent.
        //下面代码段调用PackageManagerService解析Intent(我们想要打开的App的用于启动MainActivity的Intent)
        //将解析的结果保存到ActivityInfo类型的对象里
		ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                0 /* matchFlags */,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, mRequest.filterCallingUid));
        ...                        
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        synchronized (mService) {
            ...
			//若App有ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE标记
			//App就可视为heavy-weight process,该标记可以在AndroidManifest.xml中设置
			//它是用于声明App是否享受系统提供的Activity状态保存/恢复功能的。
			//这里并不是heavy-weight process
            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
                    mService.mHasHeavyWeightFeature) {
                // This may be a heavy-weight process!  Check to see if we already
                // have another, different heavy-weight process running.
                ...
            }

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);
			...
        }
    }

	private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
			...
        	mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask, allowPendingRemoteAnimationRegistryLookup);
				...
    }

	//在这个方法中进行了大量的非法判断,比如 START_PERMISSION_DENIED/START_CLASS_NOT_FOUND
	private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
        ...
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity);
    }

	private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
        	...
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        	...
    }
}
接下来就到了非常重要的方法startActivityUnchecked,这个方法依然在ActivityStarter类中:
 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
		
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        computeLaunchingTaskFlags();
        computeSourceStack();
        mIntent.setFlags(mLaunchFlags);
        ...
            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
            mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
		...
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
		...
    }

上述代码是极限简化了的代码,只保留了一些我认为很重要的方法,当然也有一部分我还不是很理解:
setInitialState:主要功能是对当前类中变量reset,并且也对Activity的LaunchMode和LaunchFlags做了部分处理,感兴趣的可以进去看看。
computeLaunchingTaskFlags & computeSourceStack:这两个方法依然是对Activity启动LaunchFlags做了一些合法性判断和处理;还有部分是对Task的处理:比如非法状态下task部分数据的记录等等。
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);:这个方法就是通过之前计算出来的LaunchMode和LaunchFlags为即将启动的Activity设置task.
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions);:这个代码的作用就是将处理好的task相关参数,传递给WindowManager为task的切换做准备工作。


当一切准备就绪,最后调用了ActivityStackSupervisor.resumeFocusedStackTopActivityLocked:
public class ActivityStackSupervisor ...{
	boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
		...
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        ...
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
		...
    }
}
在一切正常的状态下,最终都是进入了ActivityStackresumeTopActivityUncheckedLocked的方法,最后调用到另外一个非常重要的方法resumeTopActivityInnerLocked,对于这个方法,我翻译了大量的注释:
class ActivityStack ...{

	boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        ...
            result = resumeTopActivityInnerLocked(prev, options);
		...
    }
	
	private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
		// 判断ActivityManagerService是否已经启动完毕
        if (!mService.mBooting && !mService.mBooted) {
            // Not ready yet!
            return false;
        }

        // 取得当前ActivityStack栈顶Activity的ActivityRecord
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
		...
		// 如果有正在初始化的Activity没有位于ActivityStack的栈顶,且正在执行window的启动和显示,
    	// 则要将window相关的操作取消。因为这类Activity的窗口有可能被孤立,那么它们有可能永远也不会进入resume状态
        mStackSupervisor.cancelInitializingActivities();

        // 记住我们怎样处理pause/resume状态切换,并确保无论何时结束处理都会重置状态
        boolean userLeaving = mStackSupervisor.mUserLeaving;
        mStackSupervisor.mUserLeaving = false;
		...
        // 如果当前栈顶Activity处于resume状态,且就是我们要打开的Activity,则直接return
        if (mResumedActivity == next && next.isState(RESUMED)
                && mStackSupervisor.allResumedActivitiesComplete()) {
			...
        }

        // 如果ActivityManagerService处于休眠状态,而且此时没有Activity处于resume状态
    	// 且栈顶Activity处于pause状态,则中断调度
        if (shouldSleepOrShutDownActivities()
                && mLastPausedActivity == next
                && mStackSupervisor.allPausedActivitiesComplete()) {
            ...
        }
        ...
        // 确保我们要启动的Activity没有处于stop队列、休眠队列、等待变为可见队列中
        mStackSupervisor.mStoppingActivities.remove(next);
        mStackSupervisor.mGoingToSleepActivities.remove(next);
        next.sleeping = false;
        mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
		...
        //如果当前有正在进行Pause的Activitiy,等待其完成。
        if (!mStackSupervisor.allPausedActivitiesComplete()) {
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }
		...
		//对PIP功能进行判断和赋值
        boolean lastResumedCanPip = false;
        ActivityRecord lastResumed = null;
        final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
        if (lastFocusedStack != null && lastFocusedStack != this) {
            ...
            lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
                    "resumeTopActivity", userLeaving /* beforeStopping */);
        }
        // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
        // to be paused, while at the same time resuming the new resume activity only if the
        // previous activity can't go into Pip since we want to give Pip activities a chance to
        // enter Pip before resuming the next activity.
        final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
                && !lastResumedCanPip;
		//暂停所有堆栈中的所有Activity或仅后备堆栈中的所有Activity。
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
        //mResumedActivity代表着当前栈顶处于Resume状态的Activity,如果不为空,就把他推到pause状态
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        //对startPausingLocked执行之后,Activity状态合法性的判断处理
        if (pausing && !resumeWhilePausing) {
            ...
        } else if (mResumedActivity == next && next.isState(RESUMED)
                && mStackSupervisor.allResumedActivitiesComplete()) {
            ...
        }

        //如果最近的Activities是noHistory,
        //但是因为设备进入睡眠状态而只是处于stop状态,而不是stop+finish,
        //我们需要确保完成它,因为我们正在进行最新的活动。
        if (shouldSleepActivities() && mLastNoHistoryActivity != null &&
                !mLastNoHistoryActivity.finishing) {
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                    null, "resume-no-history", false);
            mLastNoHistoryActivity = null;
        }
		...
        //确保该应用程序不再被视为已停止。
        ...
            AppGlobals.getPackageManager().setPackageStoppedState(
                    next.packageName, false, next.userId); 				
		...
        //我们正在开始下一个Activity,所以请告诉窗口管理器,前一个Activity很快就会被隐藏。 
        //这样,在计算所需的屏幕方向时,它可以知道忽略它。
        boolean anim = true;
        if (prev != null) {
            ...
            } else {
                ...
            }
        } else {
           ...
        }
        
		//设置Activityk转场动画
        if (anim) {
            next.applyOptionsLocked();
        } else {
            next.clearOptionsLocked();
        }
		...		
		//这个判断其实就是为了Activity类似翻转功能的判断,与启动并没有太大的关系
		//真正的启动在else代码块中,对于非启动流程代码,只做简单的描述
        if (next.app != null && next.app.thread != null) {
            // Activity根据各种参数,状态翻转,包括如下步骤:
            // 上一个 Activity 是否为透明
    		final boolean lastActivityTranslucent = ...
    		// 让窗口管理器重新基于新的 Activity 顺序评估屏幕的方向
   			boolean notUpdated = ...
   			if (notUpdated) {
         	// 配置发生更新无法保持已经存在的 Activity 实例
         	// 重新获取需要恢复的 Activity
         	}
         	// 准备恢复 Activity
         	transaction.setLifecycleStateRequest(
                            ResumeActivityItem.obtain(next.app.repProcState,
                                    mService.isNextTransitionForward()));
                    mService.getLifecycleManager().scheduleTransaction(transaction);
        } else {
            ....
            //这一步才是启动Activity时才会进入的方法!!!
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
		...
    }
}

在启动目标Activity之前,有一个很重要的步骤,那就是Pause当前的Activity,上述代码在pausing |= startPausingLocked(userLeaving, false, next, false);中执行Pause的逻辑,这还是很重要的:
class ActivityStack ...{
	final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
        if (prev.app != null && prev.app.thread != null) {
            ...
                mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                        PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));
            ...
        } 
    }
}

这里就到了ClientLifecycleManager类中:

class ClientLifecycleManager {
	//在startPausingLocked方法中调用该方法
	void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }
	//这里ClientTransaction的LifecycleStateRequest为 PauseActivityItem
	private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.setLifecycleStateRequest(stateRequest);
        return clientTransaction;
    }
	//最终调用该方法
	void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }
}

继续深入ClientTransactionschedule()

public class ClientTransaction ..{

	private IApplicationThread mClient;
	
	public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }
}

于是,这里依然通过Binder通信,与mClient所在的App通信,也就是与将要执行Pause状态的Activity所在的App通信,这个函数执行的就是ActivityThread中内部类:

public final class ActivityThread extends ClientTransactionHandler {
	private class ApplicationThread extends IApplicationThread.Stub {
		@Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
	}
}

于是通过ActivityThread的父类ClientTransactionHandler的方法scheduleTransaction分发msg:

public abstract class ClientTransactionHandler {
	void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

这一步又回到了ActivityThreadsendMessage方法,跳过各种sendMessage的调用,直接来看ActivityThread内部类H的处理方法handleMessage

public final class ActivityThread extends ClientTransactionHandler {

	private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
	
	class H extends Handler {
		public void handleMessage(Message msg) {
			case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    //很显然,这不是系统级别的消息
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
		}
	}
}

深入TransactionExecutor来看execute(transaction)方法:

public class TransactionExecutor {

	public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }
	//在 ActivityStack 的方法 startPausingLocked 中可以看到 ClientTransaction 并没有添加 CallBack
	//所以此处 callbacks == null 成立,不再执行其他代码
	public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null) {
            // No callbacks to execute, return early.
            return;
        }
        ...
    }
}
对于pause而言,executeLifecycleState(transaction)方法最为重要,单独分析:
public class TransactionExecutor {

	private void executeLifecycleState(ClientTransaction transaction) {
		//从上面的代码可知此处 lifecycleItem 代表的其实就是 PauseActivityItem
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        log("Resolving lifecycle state: " + lifecycleItem);

        final IBinder token = transaction.getActivityToken();
        //此处其实就是调用 ActivityThread 的 getActivityClient 的方法,通过token为键,获取Activity的信息
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }
		//PauseActivityItem中getTargetState()返回的值是:ON_PAUSE
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
	
    //此处的start:ON_RESUME, finish:ON_PAUSE,必然是finish > start 的
    //通过TransactionExecutorHelper的getLifecyclePath方法的计算
    //计算获得的path中实际上只会有ON_PAUSE,相关逻辑很简单,感兴趣可以去看下
	private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path);
    }
	
    //由上面可以最终只会有ON_PAUSE被执行
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        ...
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
		...
    }
}
经由上面流程的分析,最终由ClientTransactionHandler的子类ActivityThread(好吧,又回到ActivityThread类来了)调用handlePauseActivity,来看一系列的方法调用:
public final class ActivityThread extends ClientTransactionHandler {
	
	@Override
    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
       ...
            performPauseActivity(r, finished, reason, pendingActions);
	   ...
    }

	private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
            PendingTransactionActions pendingActions) {
            ...
            performPauseActivityIfNeeded(r, reason);
            ...
    }
	
	private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
		...
		mInstrumentation.callActivityOnPause(r.activity);
		...
	}
}

然后回到了Instrumentation

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

然后回到了Activity

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

于是Activity终于onPause了…,我想这大概就是回调地狱吧~至此,当前显示的Activity执行处于pause状态了,那么接下来就可以继续Activity启动的主流程,看一看ActivityStackSupervisor中的startSpecificActivityLocked的流程。


如果没有启动过APP,那么就先启动一个进程

在各种复杂的逻辑后终于到了比较关键的地方了,此时进入ActivityStackSupervisor类了:

public class ActivityStackSupervisor ...{
	void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // 通过要启动的Activity的信息获取到进程记录
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        getLaunchTimeTracker().setLaunchTime(r);
		//判断进程是否已经启动了,如果启动了就调用 realStartActivityLocked
        if (app != null && app.thread != null) {
            ...
                realStartActivityLocked(r, app, andResume, checkConfig);
            ...
        }
		//如果进程并没有启动,那么将相关信息告知AMS,启动相关进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
}

AMD启动进程的相关函数,关于进程的启动我了解不多,而且对Activity的启动并没有太多的参考意义,简单的记录下关键点:

public class ActivityManagerService ...{
    /**
     * @return {@code true} if process start is successful, false otherwise.
     */
    @GuardedBy("this")
    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
        ...
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            final String entryPoint = "android.app.ActivityThread";

            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        ...
    }
	
	private ProcessStartResult startProcess(String hostingType, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        ...
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        ...
    }
}

如代码所述String entryPoint = "android.app.ActivityThread“,这个参数一路从Process传递到了ZygoteProcess,并在ZygoteProcess中调用startViaZygote方法,fork出一个新的进程,并使用entryPoint,创建一个ActivityThread的实例,并调用它的main函数,于是进程创建最终还是进入到了ActivityThreadmain方法中。


ActivityThread.main
public final class ActivityThread ...{
	
	final ApplicationThread mAppThread = new ApplicationThread();
	//初始化Looper
	//Applicaion的关键代码在 thread.attach 方法中
	public static void main(String[] args) {
		...
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        Looper.loop();
        ...
    }
	//在该方法中,通过 Binder 将 ActivityThread 中 IApplicationThread 的实例传递给 AMS
	//利用 IApplicationThread 与 APP 通信
	private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            ...
        } else {
            ...
        }
        ...
    }
}

进入ActivityManagerService来分析attachApplication都做了些什么:

public class ActivityManagerService ...{

	@Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        ...
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        ...
    }

	@GuardedBy("this")
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
         ...
         //很明显,我们启动的进程不会是一个隔离的进程
         //最终都会调用到 IApplicationThread.bindApplication 
         if (app.isolatedEntryPoint != null) {
                // This is an isolated process which should just call an entry point instead of
                // being bound to an application.
                ...
            } else if (app.instr != null) {
                thread.bindApplication(params ...);
            } else {
                thread.bindApplication(params ...);
            }
         ...
         //如果要启动的 Activity 就在等待这个进程,那么在进程启动后,就调用 StackSupervisor.attachApplicationLocked
         //可以想象,启动 Activity的操作就在这个方法里面
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ...
    }
}

先来看下IApplicationThread.bindApplication做了什么事情:

public final class ActivityThread extends ClientTransactionHandler {
	
	public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, boolean autofillCompatibilityEnabled) {
			...
            AppBindData data = new AppBindData();
            ...
            sendMessage(H.BIND_APPLICATION, data);
    }
	
	class H extends Handler {
		public void handleMessage(Message msg) {
			switch (msg.what) {
				case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
             }
		}
	}
}

从上面bindApplicationH.handleMessage可以看到,它们是通过Handler来衔接的;在ActivityThread.main方法中初始化了Looper之后,涉及到APP主流程的工作,就开始使用Handler来发送消息给Looper来处理了;最后在handleMessage中来看handleBindApplication(data)这个方法:

public final class ActivityThread extends ClientTransactionHandler {
	private void handleBindApplication(AppBindData data) {
		//设置进程名
		Process.setArgV0(data.processName);
		...
		//然后创建应用的Context,也就是应用的运行上下文。
		//通过Context我们可以访问到应用相关的各种资源文件(图片、布局文件等等)
		final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        updateLocaleListFromAppContext(appContext,
                mResourcesManager.getConfiguration().getLocales());
		...
		app = data.info.makeApplication(data.restrictedBackupMode, null);
		...
		mInstrumentation.callApplicationOnCreate(app);
		...
	}
}

data.info.makeApplication方法,在创建Application的过程中,实际上最后走到了InstrumentationnewApplication方法:

public class Instrumentation {
	public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }
}

之后继续调用InstrumentationcallApplicationOnCreate方法来回调ApplicationonCreate()方法:

public class Instrumentation {
	public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
}

回到ActivityManagerService.attachApplicationLocked的流程,在Application启动完成后来到了StackSupervisor.attachApplicationLocked(app)

public class ActivityStackSupervisor ... {

	boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        ...
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    //当要启动的 Activity 的进程字段为空 &
                    //进程的 UID 与 Activity 进程ID一致
                    //进程名与Activity的进程名一致
                    //那么就可以启动Activity,并把进程app设置给Activity
                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                        	//这里top就是我们要启动的Activity,andResume 为true
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
        ...
    }
}

接下来进入正题ActivityStackSupervisor.realStartActivityLocked:

public class ActivityStackSupervisor ... {

	final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        //是否有AActivity处于pause状态
        if (!allPausedActivitiesComplete()) {
            ...
            return false;
        }
        ...
        //为Activity设置进程
        r.setProcess(app);
        //设置Activity显示状态为true
        if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */,
                    true /* isTop */)) {
                // We only set the visibility to true if the activity is allowed to be visible
                // based on
                // keyguard state. This avoids setting this into motion in window manager that is
                // later cancelled due to later calls to ensure visible activities that set
                // visibility back to false.
                r.setVisibility(true);
        }
        ...
        //为Activity的launch创建 transaction
        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
        //为 transaction 设置 Callback:LaunchActivityItem
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

        // 设置Activity的最终状态
        final ActivityLifecycleItem lifecycleItem;
        //在上一步方法 attachApplicationLocked 中已经知道
        //andResume 为 true
        if (andResume) {
              lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
        } else {
              lifecycleItem = PauseActivityItem.obtain();
        }
        //此处 lifecycleItem 为 ResumeActivityItem
        clientTransaction.setLifecycleStateRequest(lifecycleItem);

        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ...    
    }
}

于是,又与事务打交道了! 在前面分析了事务是如何将Activity推入pause状态的,我们直接进入最后一步再次分析TransactionExecutor

public class TransactionExecutor {

	public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }
}

先来分析executeCallbacks

 @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        //从前面分析可知,callbacks必定不为null,它是长度是1的列表,存在一个 LaunchActivityItem 的实例
        if (callbacks == null) {
            // No callbacks to execute, return early.
            return;
        }
        log("Resolving callbacks");
		//在前面 Instrumentation.execStartActivity 方法分析中已经描述过 token 的意义
		//此处也可以看出 token 其实代表的就是 Activity,由 token 来查找 Activity 的信息
        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        
        //此处 finalStateRequest 为 ResumeActivityItem
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            log("Resolving callback: " + item);
            // LaunchActivityItem 并没有实现  item.getPostExecutionState();
			//此处 postExecutionState != UNDEFINED 为 false
            final int postExecutionState = item.getPostExecutionState();
            // closestPreExecutionState 为 UNDEFINED
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState);
            }
			
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) {
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            }
			
            if (postExecutionState != UNDEFINED && r != null) {
                ...
            }
        }
    }

LaunchActivityItem中仅仅实现了execute方法,并没有实现postExecute,那么就来看看execute

public class LaunchActivityItem extends ClientTransactionItem {
	@Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
}

这里再次复述一下execute中的参数ClientTransactionHandler client代表的其实是ActivityThread的实例,这在pause Activity的过程中详细追踪过,这里就不赘述了。那么就来看看handleLaunchActivity

public final class ActivityThread extends ClientTransactionHandler {

	public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);
		...
        return a;
    }

	private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		...
		//为 Activity 创建上下文环境
		ContextImpl appContext = createBaseContextForActivity(r);
		Activity activity = null;
		java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
        ...
        // activity 绑定上下文环境
        activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
        ...
        if (r.isPersistable()) {
               mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
           } else {
           	   //最后走到了 Instrumentation 的 callActivityOnCreate 方法
               mInstrumentation.callActivityOnCreate(activity, r.state);
           }
        }
        //设置 Activity 当前状态为 ON_CREATE
        r.setState(ON_CREATE);
        ...
	}
}

Instrumentation.callActivityOnCreate(activity, r.state):

public class Instrumentation {

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

Activity.performCreate:

public class Activity ... {
	final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }
}

至此Activity调用了onCreate方法之后,便算是真正的创建了,然而在TransactionExecutor.execute()中还有另外一个非常重要的方法executeLifecycleState(transaction)

public class TransactionExecutor {
	/** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
    	//此处 lifecycleItem 为 ResumeActivityItem
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        ...
        
        // ResumeActivityItem.getTargetState() 返回 ON_RESUME
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

	private void cycleToPath(ActivityClientRecord r, int finish,
            boolean excludeLastState) {
        final int start = r.getLifecycleState();
        log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path);
    }
}

pause的流程不同,当前ActivityActivityThread.performLaunchActivity中已经处于ON_CREATE状态,而该事务的目标状态是ON_RESUME,我们来看下在ActivityLifecycleItem中状态的定义:

public abstract class ActivityLifecycleItem extends ClientTransactionItem {
    @Retention(RetentionPolicy.SOURCE)
    public @interface LifecycleState{}
    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;
}

再看看TransactionExecutorHelper.getLifecyclePath中的相关逻辑:

public class TransactionExecutorHelper {
	public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
        ...
        mLifecycleSequence.clear();
        if (finish >= start) {
            // just go there
            for (int i = start + 1; i <= finish; i++) {
                mLifecycleSequence.add(i);
            }
        } else { // finish < start, can't just cycle down
           ...
        }
		...
        return mLifecycleSequence;
    }
}

上述代码中,startON_CREATEfinishON_RESUME,那么mLifecycleSequence最后实际上就添加了两种状态:ON_STARTON_RESUME,此时再回到TransactionExecutor.cycleToPath中的performLifecycleSequence(r, path)这行代码的实现:

public class TransactionExecutor {

	private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            log("Transitioning to state: " + state);
            switch (state) {
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
            }
        }
    }
}

到这里,就如pausecreate的流程的分析是一样的步骤,分别调用了ActivityThreadhandleStartActivityhandleResumeActivity方法,细节不在赘述,因为大同小异。

你可能感兴趣的:(Android,总结)