Activity启动过程(一):通过ActivityThread send message启动activity

本文详细解析了Android中Activity从创建到显示的过程。从ActivityThread的main方法开始,通过attach方法启动一系列调用,最终到达ActivityStackSupervisor的attachApplicationLocked方法。在此过程中,涉及ActivityManagerService、ActivityStackSupervisor及ApplicationThread等关键组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家都知道一个应用开始的地方为ActivityThread的main方法,main方法中有以下代码:

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

下面我们看attanch方法
  1.     private void attach(boolean system) {
  2.         sCurrentActivityThread = this;
  3.         mSystemThread = system;
  4.         if (!system) {
  5.             ViewRootImpl.addFirstDrawHandler(new Runnable() {
  6.                 @Override
  7.                 public void run() {
  8.                     ensureJitEnabled();
  9.                 }
  10.             });
  11.             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
  12.                                                     UserHandle.myUserId());
  13.             RuntimeInit.setApplicationObject(mAppThread.asBinder());
  14.             final IActivityManager mgr = ActivityManagerNative.getDefault();
  15.             try {
  16.                 mgr.attachApplication(mAppThread);
  17.             } catch (RemoteException ex) {
  18.                 // Ignore
  19.             }
  20.            
  21.         } else {
  22.             // Don't set application object here -- if the system crashes,
  23.             // we can't display an alert, we just want to die die die.
  24.             android.ddm.DdmHandleAppName.setAppName("system_process",
  25.                     UserHandle.myUserId());
  26.             try {
  27.                 mInstrumentation = new Instrumentation();
  28.                 ContextImpl context = ContextImpl.createAppContext(
  29.                         this, getSystemContext().mPackageInfo);
  30.                 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
  31.                 mInitialApplication.onCreate();
  32.             } catch (Exception e) {
  33.                 throw new RuntimeException(
  34.                         "Unable to instantiate Application():" + e.toString(), e);
  35.             }
  36.         }

  37.         // 省略部分代码
  38.     }
在非system应用中,获取了一个ActivityManagerService,并将当前的app thread绑定到ActivityMangerService
在ActivityManagerNative中可以看到getDefault return gDefault.get(); gDefault定义如下:

  1.     private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
  2.         protected IActivityManager create() {
  3.             IBinder b = ServiceManager.getService("activity");
  4.             if (false) {
  5.                 Log.v("ActivityManager", "default service binder = " + b);
  6.             }
  7.             IActivityManager am = asInterface(b);
  8.             if (false) {
  9.                 Log.v("ActivityManager", "default service = " + am);
  10.             }
  11.             return am;
  12.         }
  13.     };
通过ServiceManager.getService返回一个ActivityManagerService对象,并用ActivityManagerProxy对其包装。
ServiceManager管理了常用的service,如AudioService ActivityManagerService AlarmService等(具体可参见ContextImpl中的registerService代码)。
因此这里我们查看ActivityManagerService的attachApplication方法。
    
  1.     public final void attachApplication(IApplicationThread thread) {
  2.         synchronized (this) {
  3.             int callingPid = Binder.getCallingPid();
  4.             final long origId = Binder.clearCallingIdentity();
  5.             attachApplicationLocked(thread, callingPid);
  6.             Binder.restoreCallingIdentity(origId);
  7.         }
  8.     }
主要还是调用了 attachApplicationLocked,attachApplicationLocked代码大约有240行,因此这里我们只摘取重要的部分,如下:

  1.             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
  2.                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
  3.                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
  4.                     enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
  5.                     new Configuration(mConfiguration), app.compat,
  6.                     getCommonServicesLocked(app.isolated),
  7.                     mCoreSettingsObserver.getCoreSettingsLocked());

  8.         // See if the top visible activity is waiting to run in this process...
  9.         if (normalMode) {
  10.             try {
  11.                 if (mStackSupervisor.attachApplicationLocked(app)) {
  12.                     didSomething = true;
  13.                 }
  14.             } catch (Exception e) {
  15.                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
  16.                 badApp = true;
  17.             }
  18.         }
bindApplication为绑定application对象,暂且不提,我们看下下面的那部分代码,通过注释也可以看出是将最顶部activity显示,而显示最重要的部门为mStackSupervisor.attachApplicationLocked,这里用到了一个全新的类ActivityStackSupervisor。通过命名就可以清楚这是一个activity stack管理类,然后我们进入看它的attachApplicationLocked方法。

  1.     boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
  2.         final String processName = app.processName;
  3.         boolean didSomething = false;
  4.         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
  5.             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
  6.             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
  7.                 final ActivityStack stack = stacks.get(stackNdx);
  8.                 if (!isFrontStack(stack)) {
  9.                     continue;
  10.                 }
  11.                 ActivityRecord hr = stack.topRunningActivityLocked(null);
  12.                 if (hr != null) {
  13.                     if (hr.app == null && app.uid == hr.info.applicationInfo.uid
  14.                             && processName.equals(hr.processName)) {
  15.                         try {
  16.                             if (realStartActivityLocked(hr, app, true, true)) {
  17.                                 didSomething = true;
  18.                             }
  19.                         } catch (RemoteException e) {
  20.                             Slog.w(TAG, "Exception in new application when starting activity "
  21.                                   + hr.intent.getComponent().flattenToShortString(), e);
  22.                             throw e;
  23.                         }
  24.                     }
  25.                 }
  26.             }
  27.         }
  28.         if (!didSomething) {
  29.             ensureActivitiesVisibleLocked(null, 0);
  30.         }
  31.         return didSomething;
  32.     }
经过一系列逻辑判断后最终调用到了realStartActivityLocked方法,realStartActivityLocked方法代码量大约200行,其中包括对activity task的一些逻辑操作,配置相关信息等,我们这里只关注activity启动过程,因此找到下面的代码

  1.             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
  2.                     System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
  3.                     new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
  4.                     task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
  5.                     newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
这里我们知道最终走到了ApplicationThread的scheduleLaunchActivity方法。ApplicationThread为ActivityThread的一个私有内部类.其cheduleLaunchActivity代码如下

  1.         public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
  2.                 ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
  3.                 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
  4.                 int procState, Bundle state, PersistableBundle persistentState,
  5.                 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
  6.                 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

  7.             updateProcessState(procState, false);

  8.             ActivityClientRecord r = new ActivityClientRecord();

  9.             r.token = token;
  10.             r.ident = ident;
  11.             r.intent = intent;
  12.             r.referrer = referrer;
  13.             r.voiceInteractor = voiceInteractor;
  14.             r.activityInfo = info;
  15.             r.compatInfo = compatInfo;
  16.             r.state = state;
  17.             r.persistentState = persistentState;

  18.             r.pendingResults = pendingResults;
  19.             r.pendingIntents = pendingNewIntents;

  20.             r.startsNotResumed = notResumed;
  21.             r.isForward = isForward;

  22.             r.profilerInfo = profilerInfo;

  23.             r.overrideConfig = overrideConfig;
  24.             updatePendingConfiguration(curConfig);

  25.             sendMessage(H.LAUNCH_ACTIVITY, r);
  26.         }
终于我们看到了一丝曙光,在该方法的最后一句send了一个LAUNCH_ACTIVITY的message。到这里activity启动过程讲了一半了,第二部分给大家讲ActivityThread如何接收找个message并进行activity启动的相关操作,这里我们总结一下: 
Activity启动流程,为首先系统走main方法,在main中通过attach方法,开启了一系列调用,

ActivityManagerService.attachApplication -> attachApplicationLocked -> ActivityStackSupervisor.attachApplicationLocked -> realStartActivityLocked -> ApplicationThread.scheduleLaunchActivity -> sendMessage



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值