Activity是如何打开的?

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

前言

前面写过app的启动过程和系统的启动过程,可以先了解一下

Activity启动分析

Activity的启动分为:系统app的启动,用户应用启动时在AndroidManifest.xml中配置以下intent-filter对应的Activity

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
复制代码

和应用打开后启动应用内的Activity。

系统App启动和用户应用的主Activity

android系统启动时,Zygote进程会fork SystemServer进程,SystemServer进程会启动一些系统的服务这就包括了ActivityManagerServic并创建系统上下文。以下是在初始化SystemServer.java时,调用run方法 创建系统上下文的片段,我们可以看到从这里就创建了ActivityThread并进行Attach application

private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
复制代码

下面是ActivityThread中的attach方法。


private void attach(boolean system, long startSeq) {
 //......
    if (!system) {
    //非系统启动
      //......
        try {
        //调用AMS attachApplication
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    //......
    } else {
          //..........
        try {
        //.....创建application
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
         
        }
    }
//..........
}
复制代码

attach中的入参boolean system判断是系统启动时还是用户应用启动。如果是系统启动的话,则会创建Application并调用oncreate方法,如果是用户App启动的话则会调用AMS attachApplication方法,接着调用 attachApplicationLocked方法

private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
//......
if (app.getIsolatedEntryPoint() != null) {
    // This is an isolated process which should just call an entry point instead of
    // being bound to an application.
    //这块判断如果是入口点则会运行ActivityThread的main()方法
    thread.runIsolatedEntryPoint(
            app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
            
} else if (instr2 != null) {
     //判断 ProcessRecord 是否存在Instrumention对象,如果不为空直接从instrumention获取信息
    thread.bindApplication(processName, appInfo, providerList,
            instr2.mClass,
            profilerInfo, instr2.mArguments,
            instr2.mWatcher,
            instr2.mUiAutomationConnection, testMode,
            mBinderTransactionTrackingEnabled, enableTrackAllocation,
            isRestrictedBackupMode || !normalMode, app.isPersistent(),
            new Configuration(app.getWindowProcessController().getConfiguration()),
            app.getCompat(), getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked(),
            buildSerial, autofillOptions, contentCaptureOptions,
            app.getDisabledCompatChanges(), serializedSystemFontMap);
} else {
    thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
            null, null, null, testMode,
            mBinderTransactionTrackingEnabled, enableTrackAllocation,
            isRestrictedBackupMode || !normalMode, app.isPersistent(),
            new Configuration(app.getWindowProcessController().getConfiguration()),
            app.getCompat(), getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked(),
            buildSerial, autofillOptions, contentCaptureOptions,
            app.getDisabledCompatChanges(), serializedSystemFontMap);
}
    return true;
}
复制代码

可以看到随后调用了ActivityThread中的bindApplication方法,我们继续跟进bindApplication方法

@Override
public final void bindApplication(....) {
    //........

    AppBindData data = new AppBindData();
    data.processName = processName;
    //......
    //调用Handler创建Application 
    sendMessage(H.BIND_APPLICATION, data);
}

public void handleMessage(Message msg) {
    switch (msg.what) {
        case BIND_APPLICATION:
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
            //........
}
复制代码

可以看到最终使用Handler创建application并调用oncreate方法

应用内的Activity启动

从上面已经看到activity启动最终会交付于ATMS的startActivity

@Override
public final int startActivity(..) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());

    //startActivity最终会调用startActivityAsUser
private int startActivityAsUser(...);

    userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
    // getActivityStartController().obtainStarter()是一个ActivityStarter对象
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();

}

复制代码

至此 又到了StartStarter对象中。执行execute方法。execute最终又调用到了 ActivityStackSupervisor中的realStartActivityLocked方法。

扫描二维码关注公众号,回复: 13370596 查看本文章
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {

            //......省略N多代码

            // 创建启动activity的事物clientTransaction
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
            //省略N多代码

            //通过ClientLifecycleManager提交事物
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
复制代码

我们继续跟进到CLientLifecycleMnager找到scheduleTransaction方法

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();
    }
}
复制代码
private IApplicationThread mClient;

public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}
复制代码

可以看到mClient是applicationThread对象

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}
复制代码

继续从ActivityThread的父类ClientTransactionHandler调用scheduleTransaction

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

//在ActivityThread中使用Handler处理消息
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    break;
    
  //  mTransactionExecutor.execute()
public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    if (token != null) {
        final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
                mTransactionHandler.getActivitiesToBeDestroyed();
        final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
        if (destroyItem != null) {
            if (transaction.getLifecycleStateRequest() == destroyItem) {
                // It is going to execute the transaction that will destroy activity with the
                // token, so the corresponding to-be-destroyed record can be removed.
                activitiesToBeDestroyed.remove(token);
            }
            if (mTransactionHandler.getActivityClient(token) == null) {
                // The activity has not been created but has been requested to destroy, so all
                // transactions for the token are just like being cancelled.
                Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
                        + transactionToString(transaction, mTransactionHandler));
                return;
            }
        }
    }

        //省略N多代码
    executeCallbacks(transaction);
    executeLifecycleState(transaction);
}
public void executeCallbacks(ClientTransaction transaction) {
        //省略N多代码
        

  // 最开始在ActivityStackSupervisor#realStartActivityLocked中实例化ClientTransaction时  addCallback传入的是LaunchActivityItem; //所以这里执行的其实是LaunchActivityItem.execute方法
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
}
复制代码

从上面代码注释中可以知道我们最终调用的是LaunchActivityItem.execute方法

@Override
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
            //因为ActivityThread继承ClientTransactionHandler,所以最终 调用了ActivityThread的handleLaunchActivity
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
复制代码

handlerActivity中又调用了performLaunchActivity,从下面官网注释中可以发现这是启动activity的核心方法

/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    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);
    }

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

    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());

        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }

            // Activity resources must be initialized with the same loaders as the
            // application context.
            appContext.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

            appContext.setOuterContext(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,
                    r.assistToken);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }

            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()");
            }
            r.activity = activity;
            mLastReportedWindowingMode.put(activity.getActivityToken(),
                    config.windowConfiguration.getWindowingMode());
        }
        r.setState(ON_CREATE);

        // updatePendingActivityConfiguration() reads from mActivities to update
        // ActivityClientRecord which runs in a different thread. Protect modifications to
        // mActivities to avoid race.
        synchronized (mResourcesManager) {
            mActivities.put(r.token, r);
        }

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }

    return activity;
}
复制代码

从上面代码中可以看到我们应用中重要的application window的身影还有activity的attach调用。至此activity已经完全启动

//啊 终于完了历时两天 太累了。。。。。。。。。。。。。里面还有很多细节 分析不了了。。

猜你喜欢

转载自juejin.im/post/7034508887025778702