第九章-四大组件的工作过程(Activity的启动过程-基于Android9.0源码)

四大组件的运行状态

这里是引用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、Activity的工作过程
Activity作为很重要的一个组件,其内部工作过程系统做了很多的封装,这使得启动一个Activity变得异常简单。在显示调用的情况下,只需要通过如下代码即可完成:

Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);

通过上面的代码即可启动一个具体的Activity了,然后新的Activity就会被系统启动并展示在用户的眼前。这个过程对于Android开发者再熟悉不过了,这也是很理所当然的事,但是有没有想过系统内部到底是如何启动Activity的呢?比如新Activity的对象是在何时创建的?Activity的onCreate方法又是在何时被系统回调的呢?在日常开发中是不需要了解系统的底层工作原理的,但是如果想在技术的领域更上一层楼,就很有必要知道系统的工作原理了。

在这里插入图片描述

    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);//调用到了Instrumention里面的execStartActivity方法。
            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);
            }
        }
    }

在这里插入图片描述

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    ActivityResult result = null;
                    if (am.ignoreMatchingSpecificIntents()) {
                        result = am.onStartActivity(intent);
                    }
                    if (result != null) {
                        am.mHits++;
                        return result;
                    } else if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);//可以看到这里通过Binder调用到了AMS中去了
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

在这里插入图片描述
我们看下ActivityTaskManager.getService()代码:

    /** @hide */
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                //public static final String ACTIVITY_TASK_SERVICE = "activity_task";
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);//这里就拿到了服务的Binder类
                    return IActivityTaskManager.Stub.asInterface(b);//和之前的AIDL一样,将服务端Binder转化为IActivityTaskManager,可以直接在本地调用到AMS中的方法了。 
                }
            };

总结:到这里,启动的逻辑就通过IPC转移到了AMS中了。我们只需要看AMS中的startActivity方法即可。
在分析AMS的startActivity方法之前,我们先看下Instrumentation中的execStartActivity方法中有 checkStartActivityResult(result, intent); 这一行代码。直观上看这个是检查activity的启动结果(实际也是如此的),代码如下:
在这里插入图片描述
从上面的代码看出,checkStartActivityResult方法作用很明显,就是检查启动Activity的结果。当无法正确启动一个Activity的时候,就是抛出异常信息。

接着我们继续分析AMS中的startActivity方法:

    @Override
    public int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            //public ActivityTaskManagerService mActivityTaskManager;定义
        return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
                //可以看到调用到ActivityTaskManagerService 中去了
    }

在这里插入图片描述
备注:在Android9.0上的代码和书上的有些差异,但是流程都差不多。
可以看出,最后又转移到了ActivityStarter的startActivityMayWait方法中,在startActivityMayWait中又调用了startActivityLocked方法,在startActivityLocked中又调用了startActivityUnchecked,紧接着有调用了resumeTopActivityUncheckedLocked方法,这个时候启动过程已经从ActivityStackSupervisor转移到了ActivityStack,可以看如下代码:

    @GuardedBy("mService")
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);

            // When resuming the top activity, it may be necessary to pause the top activity (for
            // example, returning to the lock screen. We suppress the normal pause logic in
            // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
            // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
            // to ensure any necessary pause logic occurs. In the case where the Activity will be
            // shown regardless of the lock screen, the call to
            // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return result;
    }

上面这段代码中,resumeTopActivityUncheckedLocked又调用了resumeTopActivityInnerLocked,resumeTopActivityInnerLocked又调用了ActivityStackSupervisor的startSpecificActivityLocked,startSpecificActivityLocked的源码如下所示:

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                realStartActivityLocked(r, wpc, 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.
            knownToBeDead = true;
        }

        // Suppress transition until the new activity becomes ready, otherwise the keyguard can
        // appear for a short amount of time before the new process with the new activity had the
        // ability to set its showWhenLocked flags.
        if (getKeyguardController().isKeyguardLocked()) {
            r.notifyUnknownVisibilityLaunched();
        }

        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

最后又调用了realStartActivityLocked,我们来看下图了解ActivityStack和ActivityStackSupervisor之间的互相传递过程
在这里插入图片描述

备注:下面的分析是基于Android9.0的代码分析和书上的代码有些差异。
在ActivityStackSupervisor.realStartActivityLocked方法中为ClientTransaction对象添加LaunchActivityItem的callback,然后设置当前的生命周期状态,最后调用ClientLifecycleManager.scheduleTransaction方法执行。
在这里插入图片描述
最终调用到ClientTransaction的schedule方法。

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

ClientTransaction.schedule方法的mClient是一个IApplicationThread类型,ActivityThread的内部类ApplicationThread派生这个接口类并实现了对应的方法。所以直接跳转到ApplicationThread中的scheduleTransaction方法ActivityThread类中并没有定义scheduleTransaction方法,所以调用的是他父类ClientTransactionHandler的scheduleTransaction方法。

解析说明如下:
在这里插入图片描述
ApplicationThread的scheduleTransaction方法:

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);//看到调用了ActivityThread的这个方法
            //而ActivityThread没有实现该方法,所以调用父类ClientTransactionHandler的这个方法。
            //public final class ActivityThread extends ClientTransactionHandler {
        }

ClientTransactionHandler的方法:(发送了一条消息给ActivityThread)

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

在ClientTransactionHandler.scheduleTransaction方法中调用了sendMessage方法,这个方法是一个抽象方法,其实现在ClientTransactionHandler派生类的ActivityThread中。

    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);//定义:final H mH = new H();
    }

ActivityThread.sendMessage方法会把消息发送给内部名字叫H的Handler。
看下H对EXECUTE_TRANSACTION处理方式:

                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);//看到调用到了execute方法
                    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;

Handler H的实例接收到EXECUTE_TRANSACTION消息后调用TransactionExecutor.execute方法切换Activity状态。TransactionExecutor.execute方法里面先执行Callbacks,然后改变Activity当前的生命周期状态。

    frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
    public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        ...
    }

    public void executeCallbacks(ClientTransaction transaction) {
        if (callbacks == null) {
            // No callbacks to execute, return early.
            return;
        }
        ...
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            ...
            item.execute(mTransactionHandler, token, mPendingActions);//这个其实就是执行了我们定义的LaunchActivityItem里面的execute方法。
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...
        }
    }

    /** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        ...

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

可以看到我们之前在AMS中设置了callback:

	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, proc.getReportedProcState(),
		r.icicle, r.persistentState, results, newIntents,
		dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
				r.assistToken));


	//clientTransaction的addCallback定义如下:
    public void addCallback(ClientTransactionItem activityCallback) {
        if (mActivityCallbacks == null) {
            mActivityCallbacks = new ArrayList<>();
        }
        mActivityCallbacks.add(activityCallback);
    }

执行callback后跳转到LaunchActivityItem.execute方法。

    frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ...
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
    
    frameworks/base/core/java/android/app/ActivityThread.java
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
    }

可以看到我们最终执行到了ActivitityThread中的performLaunchActivity方法了。

========有个疑问,client.handleLaunchActivity(r, pendingActions, null /* customIntent */);怎么就调到ActivityThread中的handleLaunchActivity方法呢?

//ActivitityThread中的mTransactionExecutor初始化
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

//TransactionExecutor的构造
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
    mTransactionHandler = clientTransactionHandler;
}

//这里就可以看到mTransactionHandler 这个对象就是ActivityThread

//executeCallbacks方法中的代码,将mTransactionHandler传递给了LaunchActivityItem.java中的execute方法。
item.execute(mTransactionHandler, token, mPendingActions);

所以这里的client.handleLaunchActivity,就是调用的ActivityThread中的handleLaunchActivity方法。

========疑问已解答

到这里我们的代码就比较清晰了。看看performLaunchActivity这个方法主要完成的作用。

1.从ActivityClientRecord中获取待启动的Activity组件信息

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

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

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

2.通过instrumentation的newActivity方法使用类加载器创建Activity对象

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

至于instrumentation的newActivity,他的实现就比较简单,就是通过类加载器创建

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        return getFactory(pkg).instantiateActivity(cl, className, intent);
    }

3.通过LoadedApk的makeApplicatiton方法来创建Application对象

Application app = r.packageInfo.makeApplication(false, mInstrumentation);
public Application makeApplication(boolean forceDefaultAppClass,
		Instrumentation instrumentation) {
	if (mApplication != null) {
		return mApplication;
	}

	Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

	Application app = null;

	String appClass = mApplicationInfo.className;
	if (forceDefaultAppClass || (appClass == null)) {
		appClass = "android.app.Application";
	}

	try {
		java.lang.ClassLoader cl = getClassLoader();
		if (!mPackageName.equals("android")) {
			Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
					"initializeJavaContextClassLoader");
			initializeJavaContextClassLoader();
			Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
		}
		ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
		app = mActivityThread.mInstrumentation.newApplication(
				cl, appClass, appContext);
		appContext.setOuterContext(app);
	} catch (Exception e) {
		if (!mActivityThread.mInstrumentation.onException(app, e)) {
			Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
			throw new RuntimeException(
				"Unable to instantiate application " + appClass
				+ ": " + e.toString(), e);
		}
	}
	mActivityThread.mAllApplications.add(app);
	mApplication = app;

	if (instrumentation != null) {
		try {
			instrumentation.callApplicationOnCreate(app);//调用Application的onCreate的方法
		} catch (Exception e) {
			if (!instrumentation.onException(app, e)) {
				Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
				throw new RuntimeException(
					"Unable to create application " + app.getClass().getName()
					+ ": " + e.toString(), e);
			}
		}
	}
...

	return app;
}

在这里插入图片描述

4.创建ContextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化
在这里插入图片描述

ContextImpl是一个很重要的数据结构,它是Context的具体实现,Context中的大部分逻辑都是ContextImpl来处理的。ContextImpl是通过Activity的attach方法和Activity建立关联的,除此之外,在attach方法中Activity还会完成Window的创建并且建立自己和Window的关联。这样当Window接收到外部输入的事件后就可以将事件传递给Activity。

5.调用Activity的onCreate

	activity.mCalled = false;
	if (r.isPersistable()) {
		mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
	} else {
		mInstrumentation.callActivityOnCreate(activity, r.state);
	}
	if (!activity.mCalled) {
		throw new SuperNotCalledException(
			"Activity " + r.intent.getComponent().toShortString() +
			" did not call through to super.onCreate()");
	}

mInstrumentation.callActivityOnCreate(activity, r.state);,由于Activity的onCreate已经被调用,这也意味着Activity完成了整个启动过程。

到这里Activity的启动过程就分析完成了。我是在Android9.0的源码下查阅的。和书上的代码有些差异。但是分析的流程都类似。

总结:整体的启动大概就是app发起一个启动activity的请求,通过Binder的IPC过程将启动交给AMS来处理。AMS中经过多重方法的调用,数据处理。最终也会通过Binder的IPC来回调到周期函数。初始化数据。最终完成整个流程的启动。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章