前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Activity 创建流程详解

Activity 创建流程详解

原创
作者头像
大发明家
发布2021-12-15 15:22:23
7610
发布2021-12-15 15:22:23
举报
文章被收录于专栏:技术博客文章

创建流程

ActivityThread作为主应用程序的主线程管理类,我们都从main方法开始分析。main方法主要功能是创建ActivityThread且关联,创建Looper死循环不让程序退出。

代码语言:txt
复制
public static void main(String[] args) {
代码语言:txt
复制
        ...
代码语言:txt
复制
        //为主线程创建loop对象,我们在主线程使用Handler时候没有初始化都可以使用,因为这里做了初始化。
代码语言:txt
复制
        Looper.prepareMainLooper();
代码语言:txt
复制
        ...
代码语言:txt
复制
        ActivityThread thread = new ActivityThread();
代码语言:txt
复制
        thread.attach(false, startSeq);
代码语言:txt
复制
        if (sMainThreadHandler == null) {
代码语言:txt
复制
            sMainThreadHandler = thread.getHandler();
代码语言:txt
复制
        }
代码语言:txt
复制
        //开始死循环获得消息
代码语言:txt
复制
        Looper.loop();
代码语言:txt
复制
    }

接下来我们分析一下ActivityThread的attach方法,在调用attach时候第一个参数传递的是false,我们可以看出它通过AMS跨进程调用了attachApplication方法。

代码语言:txt
复制
 private void attach(boolean system, long startSeq) {
代码语言:txt
复制
        if (!system) {
代码语言:txt
复制
             ...
代码语言:txt
复制
            final IActivityManager mgr = ActivityManager.getService();
代码语言:txt
复制
            try {
代码语言:txt
复制
                mgr.attachApplication(mAppThread, startSeq);
代码语言:txt
复制
            } catch (RemoteException ex) {
代码语言:txt
复制
                throw ex.rethrowFromSystemServer();
代码语言:txt
复制
            }
代码语言:txt
复制
        }
代码语言:txt
复制
        ...
代码语言:txt
复制
    }

接下来我们需要去framework看AMS源码才能只知道里面到底做了什么事情,

最后调用了attachApplicationLocked方法,然后回调到主进程ApplicationThread的bindApplication方法里面去。

代码语言:txt
复制
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
代码语言:txt
复制
 private final boolean attachApplicationLocked(IApplicationThread thread,
代码语言:txt
复制
                                                  int pid, int callingUid, long startSeq) {
代码语言:txt
复制
        ...
代码语言:txt
复制
        thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
代码语言:txt
复制
                null, null, null, testMode,
代码语言:txt
复制
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
代码语言:txt
复制
                isRestrictedBackupMode || !normalMode, app.isPersistent(),
代码语言:txt
复制
                new Configuration(app.getWindowProcessController().getConfiguration()),
代码语言:txt
复制
                app.compat, getCommonServicesLocked(app.isolated),
代码语言:txt
复制
                mCoreSettingsObserver.getCoreSettingsLocked(),
代码语言:txt
复制
                buildSerial, autofillOptions, contentCaptureOptions);
代码语言:txt
复制
        ...
代码语言:txt
复制
        didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
代码语言:txt
复制
        ...
代码语言:txt
复制
    }

我们继续分析主进程ActivityThread,AMS通知它创建Application,且两个进程之间数据同步。

代码语言:txt
复制
public final void bindApplication(String processName, ApplicationInfo appInfo,
代码语言:txt
复制
                List<ProviderInfo> providers, ComponentName instrumentationName,
代码语言:txt
复制
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
代码语言:txt
复制
                IInstrumentationWatcher instrumentationWatcher,
代码语言:txt
复制
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
代码语言:txt
复制
                boolean enableBinderTracking, boolean trackAllocation,
代码语言:txt
复制
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
代码语言:txt
复制
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
代码语言:txt
复制
                String buildSerial, AutofillOptions autofillOptions,
代码语言:txt
复制
                ContentCaptureOptions contentCaptureOptions) {
代码语言:txt
复制
            ...
代码语言:txt
复制
            AppBindData data = new AppBindData();
代码语言:txt
复制
            data.processName = processName;
代码语言:txt
复制
            data.appInfo = appInfo;
代码语言:txt
复制
            data.providers = providers;
代码语言:txt
复制
            data.instrumentationName = instrumentationName;
代码语言:txt
复制
            data.instrumentationArgs = instrumentationArgs;
代码语言:txt
复制
            data.instrumentationWatcher = instrumentationWatcher;
代码语言:txt
复制
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
代码语言:txt
复制
            data.debugMode = debugMode;
代码语言:txt
复制
            data.enableBinderTracking = enableBinderTracking;
代码语言:txt
复制
            data.trackAllocation = trackAllocation;
代码语言:txt
复制
            data.restrictedBackupMode = isRestrictedBackupMode;
代码语言:txt
复制
            data.persistent = persistent;
代码语言:txt
复制
            data.config = config;
代码语言:txt
复制
            data.compatInfo = compatInfo;
代码语言:txt
复制
            data.initProfilerInfo = profilerInfo;
代码语言:txt
复制
            data.buildSerial = buildSerial;
代码语言:txt
复制
            data.autofillOptions = autofillOptions;
代码语言:txt
复制
            data.contentCaptureOptions = contentCaptureOptions;
代码语言:txt
复制
            sendMessage(H.BIND_APPLICATION, data);//1
代码语言:txt
复制
        }

我们从上面代码看出第一点,在ApplicationThread通过H类是继承Handler,通过发送消息到主线程管理类ActivityThread执行绑定Application,调用handleBindApplication方法。创建LoadedApk对象并且用于创建Application。

代码语言:txt
复制
    private void handleBindApplication(AppBindData data) {
代码语言:txt
复制
        //设置进程名字
代码语言:txt
复制
        Process.setArgV0(data.processName);
代码语言:txt
复制
        //创建LoadedApk实例
代码语言:txt
复制
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
代码语言:txt
复制
        app = data.info.makeApplication(data.restrictedBackupMode, null);
代码语言:txt
复制
    }
代码语言:txt
复制
  public Application makeApplication(boolean forceDefaultAppClass,
代码语言:txt
复制
                                       Instrumentation instrumentation) {
代码语言:txt
复制
        //1
代码语言:txt
复制
        if (mApplication != null) {
代码语言:txt
复制
            return mApplication;
代码语言:txt
复制
        }
代码语言:txt
复制
        Application app = null;
代码语言:txt
复制
        try {
代码语言:txt
复制
            ClassLoader cl = getClassLoader();
代码语言:txt
复制
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
代码语言:txt
复制
            //2
代码语言:txt
复制
            app = mActivityThread.mInstrumentation.newApplication(
代码语言:txt
复制
                    cl, appClass, appContext);
代码语言:txt
复制
            appContext.setOuterContext(app);
代码语言:txt
复制
        } catch (Exception e) {
代码语言:txt
复制
        }
代码语言:txt
复制
        mApplication = app;
代码语言:txt
复制
        if (instrumentation != null) {
代码语言:txt
复制
            //3
代码语言:txt
复制
            instrumentation.callApplicationOnCreate(app);
代码语言:txt
复制
        }
代码语言:txt
复制
        return app;
代码语言:txt
复制
    }

从上述代码我们可以看出,

1:如果有已经创建好了Applicaiton对象及返回。

2:创建Application对象,并且与appContext建立关联关系,且调用attach方法

3:通过instrumentation调用执行onCreate方法

然后我们在回到AMS代码里面及方法attachApplicationLocked,看看是如何执行跳转Activity的。

代码语言:txt
复制
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
代码语言:txt
复制
      public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
代码语言:txt
复制
        synchronized (mGlobalLockWithoutBoost) {
代码语言:txt
复制
            return mRootActivityContainer.attachApplication(wpc);
代码语言:txt
复制
      }

我们可以看出下面代码realStartActivityLocked,这个都是我们真正发起创建Activity的方法,然后我们继续分析代码。

代码语言:txt
复制
//frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
代码语言:txt
复制
        boolean attachApplication(WindowProcessController app) throws RemoteException {
代码语言:txt
复制
        final String processName = app.mName;
代码语言:txt
复制
        boolean didSomething = false;
代码语言:txt
复制
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
代码语言:txt
复制
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
代码语言:txt
复制
            final ActivityStack stack = display.getFocusedStack();
代码语言:txt
复制
            if (stack != null) {
代码语言:txt
复制
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
代码语言:txt
复制
                final ActivityRecord top = stack.topRunningActivityLocked();
代码语言:txt
复制
                final int size = mTmpActivityList.size();
代码语言:txt
复制
                for (int i = 0; i < size; i++) {
代码语言:txt
复制
                    final ActivityRecord activity = mTmpActivityList.get(i);
代码语言:txt
复制
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
代码语言:txt
复制
                            && processName.equals(activity.processName)) {
代码语言:txt
复制
                        try {
代码语言:txt
复制
                            //执行跳转
代码语言:txt
复制
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
代码语言:txt
复制
                                    top == activity /* andResume */, true /* checkConfig */)) {
代码语言:txt
复制
                                didSomething = true;
代码语言:txt
复制
                            }
代码语言:txt
复制
                        } catch (RemoteException e) {
代码语言:txt
复制
                           }
代码语言:txt
复制
                    }
代码语言:txt
复制
                }
代码语言:txt
复制
            }
代码语言:txt
复制
        }
代码语言:txt
复制
        return didSomething;
代码语言:txt
复制
    }

在下面的代码主要作用是,发送指令到应用进程创建Activity,LaunchActivityItem表示一个创建任务。

代码语言:txt
复制
//frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
代码语言:txt
复制
 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
代码语言:txt
复制
                                    boolean andResume, boolean checkConfig) throws RemoteException {
代码语言:txt
复制
        //启动指令
代码语言:txt
复制
     clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
代码语言:txt
复制
                System.identityHashCode(r), r.info,
代码语言:txt
复制
                // TODO: Have this take the merged configuration instead of separate global
代码语言:txt
复制
                // and override configs.
代码语言:txt
复制
                mergedConfiguration.getGlobalConfiguration(),
代码语言:txt
复制
                mergedConfiguration.getOverrideConfiguration(), r.compat,
代码语言:txt
复制
                r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
代码语言:txt
复制
                r.icicle, r.persistentState, results, newIntents,
代码语言:txt
复制
                dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
代码语言:txt
复制
                r.assistToken));
代码语言:txt
复制
        // Set desired final state.
代码语言:txt
复制
        final ActivityLifecycleItem lifecycleItem;
代码语言:txt
复制
        if (andResume) {
代码语言:txt
复制
            lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
代码语言:txt
复制
        } else {
代码语言:txt
复制
            lifecycleItem = PauseActivityItem.obtain();
代码语言:txt
复制
        }
代码语言:txt
复制
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
代码语言:txt
复制
        // Schedule transaction. 跨进程调用到应用进程
代码语言:txt
复制
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
代码语言:txt
复制
        return true;
代码语言:txt
复制
    }

于是开始执行命令到,

代码语言:txt
复制
//ClientLifecycleManager.java
代码语言:txt
复制
 void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
代码语言:txt
复制
        final IApplicationThread client = transaction.getClient();
代码语言:txt
复制
        transaction.schedule();
代码语言:txt
复制
        if (!(client instanceof Binder)) {
代码语言:txt
复制
            transaction.recycle();
代码语言:txt
复制
        }
代码语言:txt
复制
    }
代码语言:txt
复制
//ClientTransaction.java
代码语言:txt
复制
public void schedule() throws RemoteException {
代码语言:txt
复制
        mClient.scheduleTransaction(this);
代码语言:txt
复制
    }

上述代码mClient实际都是ApplicationThread,那我们由此知道,马上都会创建真正的Activity了,接下来我们继续分析,我们来到ApplicationThread这个类里面的这个scheduleTransaction方法。

代码语言:txt
复制
//ClientTransactionHandler.java
代码语言:txt
复制
 void scheduleTransaction(ClientTransaction transaction) {
代码语言:txt
复制
        transaction.preExecute(this);
代码语言:txt
复制
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
代码语言:txt
复制
    }

上述代码看出,最终代买执行到了ActivityThread,然后通过发送消息到主线程管理执行创建Activity,ActivityThread继承了ClientTransactionHandler。

代码语言:txt
复制
    //TransactionExecutor.java
代码语言:txt
复制
    public void execute(ClientTransaction transaction) {
代码语言:txt
复制
        executeCallbacks(transaction);
代码语言:txt
复制
       //之前执行暂停调用这个方法
代码语言:txt
复制
        executeLifecycleState(transaction);
代码语言:txt
复制
    }
代码语言:txt
复制
    public void executeCallbacks(ClientTransaction transaction) {
代码语言:txt
复制
        for (int i = 0; i < size; ++i) {
代码语言:txt
复制
            final ClientTransactionItem item = callbacks.get(i);
代码语言:txt
复制
            item.execute(mTransactionHandler, token, mPendingActions);
代码语言:txt
复制
            item.postExecute(mTransactionHandler, token, mPendingActions);
代码语言:txt
复制
        }
代码语言:txt
复制
    }

经过上述代码的表演,我们来到了LaunchActivityItem这个类。

代码语言:txt
复制
@Override
代码语言:txt
复制
    public void execute(ClientTransactionHandler client, IBinder token,
代码语言:txt
复制
            PendingTransactionActions pendingActions) {
代码语言:txt
复制
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
代码语言:txt
复制
        //与 ActivityRecord 信息同步  token信息通讯
代码语言:txt
复制
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
代码语言:txt
复制
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
代码语言:txt
复制
                mPendingResults, mPendingNewIntents, mIsForward,
代码语言:txt
复制
                mProfilerInfo, client, mAssistToken);
代码语言:txt
复制
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
代码语言:txt
复制
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
代码语言:txt
复制
    }

走到这里我们开始创建ActivityClientRecord来记录Activity的信息,并且通过token与AMS的ActivityRecord相应关联。继续看handleLaunchActivity的源码,如下。

代码语言:txt
复制
    public Activity handleLaunchActivity(ActivityClientRecord r,
代码语言:txt
复制
            PendingTransactionActions pendingActions, Intent customIntent) {
代码语言:txt
复制
        final Activity a = performLaunchActivity(r, customIntent);
代码语言:txt
复制
        return a;
代码语言:txt
复制
    }
代码语言:txt
复制
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
代码语言:txt
复制
        ContextImpl appContext = createBaseContextForActivity(r);
代码语言:txt
复制
        Activity activity = null;
代码语言:txt
复制
        try {
代码语言:txt
复制
            ClassLoader cl = appContext.getClassLoader();
代码语言:txt
复制
            activity = mInstrumentation.newActivity(
代码语言:txt
复制
                    cl, component.getClassName(), r.intent);
代码语言:txt
复制
        } catch (Exception e) {
代码语言:txt
复制
        }
代码语言:txt
复制
        try {
代码语言:txt
复制
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
代码语言:txt
复制
            if (activity != null) {
代码语言:txt
复制
                appContext.setOuterContext(activity);
代码语言:txt
复制
                activity.attach(appContext, this, getInstrumentation(), r.token,
代码语言:txt
复制
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
代码语言:txt
复制
                        r.embeddedID, r.lastNonConfigurationInstances, config,
代码语言:txt
复制
                        r.referrer, r.voiceInteractor, window, r.configCallback,
代码语言:txt
复制
                        r.assistToken);
代码语言:txt
复制
                if (r.isPersistable()) {
代码语言:txt
复制
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
代码语言:txt
复制
                } else {
代码语言:txt
复制
                    mInstrumentation.callActivityOnCreate(activity, r.state);
代码语言:txt
复制
                }
代码语言:txt
复制
                r.activity = activity;
代码语言:txt
复制
            }
代码语言:txt
复制
        } catch (SuperNotCalledException e) {
代码语言:txt
复制
            throw e;
代码语言:txt
复制
        } catch (Exception e) {
代码语言:txt
复制
        }
代码语言:txt
复制
        return activity;
代码语言:txt
复制
    }

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档