Activity 原生启动流程分析

admin 2025年6月11日23:45:59评论17 views字数 17151阅读57分10秒阅读模式

系统界面 Launcher

在 Android 系统启动以后,系统已经启动了 Zygote,ServiceManager,SystemServer 等系统进程。

ServiceManager进程中完成了Binder初始化;SystemServer进程中 ActivityManagerService,WindowManagerServicePackageManagerService等系统服务在ServiceManager中已经注册;最后启动了Launcher桌面应用。

Activity 原生启动流程分析

Launcher作为用户的交互界面,在用户点击 APP 图标的时候提供了打开应用的能力。不同的手机厂商可能会根据Launcher做一些定制,比如miui就是如此,但最终的原理是一致的。

应用安装的时候,通过PackageManagerService解析 apk 的AndroidManifest.xml文件,提取出这个 apk 的信息写入到packages.xml文件中,这些信息包括:权限、应用包名、icon、apk 的安装位置、版本、userID 等等。packages.xml 文件位于系统目录下/data/system/packages.xml。

启动应用流程

Activity 原生启动流程分析

当用户点击桌面上的应用图标后,Launcher 会通过 service_manager 向 AMS 服务发出请求,查询对应的 APP 信息,然后由 Zygote 创建目标 APP 进程。

Activity 原生启动流程分析

先梳理一下大致的流程:

1.Launcher 通过 Binder 方式沟通 AMS

2.AMS 先检查这个 APP 进程是不是已经创建了

3.如果已经创建,则直接调用realStartActivityLocked直接到第 7 步

4.否则,AMS 接到请求后让 Zygote 通过 fork 创建 APP 进程,完成Application.onCreate、创建应用的上下文和其他各种必要对象,这些对象会在 AMS 中留有备份进行保留。

5.新创建的 APP 进程通过 Binder 发送ATTACH_APPLICATION_TRANSACTION通知 AMS

6.AMS 接到ATTACH_APPLICATION_TRANSACTION后调用realStartActivityLocked

7.设置进程为顶部 Activity,为新进程创建事务发送调度命令H.EXECUTE_TRANSACTION

8.进程处理命令消息时调用 Activity.onCreate 并且初始化应用自己的视图

具体到代码实现中,分为几个步骤,首先启动步骤从 Launcher 开始:

1.检查将要打开的目标 APP 的 Activity 是否存在,如果存在就不需要打开了

Launcher.startActivitySafel->Launcher.startActivity

2.打开目标 Activity

Activity.startActivity

3.通过 ATSM 服务调用该服务提供的 startActivity

Activity.startActivityForResult-Instrumentation.execStartActivity-ActivityTaskManager.getService().startActivity

ActivityManagerNative.getDefault()会返回一个ActivityManagerProxy作为 Launcher 中使用ActivityTaskManager的代理,该代理的 startActivity 会发送START_ACTIVITY_TRANSACTION来通知ActivityTaskManager

完成上述过程后,进程从Launcher切换到system_server中的ActivityManagerService,也就是 AMS。

在 startActivityAsUser 中会先获取用户的 UserID 作为参数然后往下调用 getActivityStartController 中的 starter

startActivity-startActivityAsUser

创建新的 intent 对象,获取 ApplicationPackageManager

ActivityStackSupervisor.startActivityMayWait-resolveActivity

获取 intent 所指向的 Activity 信息,并保存到 Intent 对象。

PackageManagerService.resolveIntent()-queryIntentActivities()

-获取到调用者的进程信息,通过Intent.FLAG_ACTIVITY_FORWARD_RESULT判断是否需要进行startActivityForResult处理。检查调用者是否有权限来调用指定的 Activity

-Activity 有多种启动模式,对 launchMode 的处理,创建 Task 等操作。启动 Activity 所在进程,已存在则直接onResume(),不存在则创建 Activity 并处理是否触发onNewIntent()

ActivityStackSupervisor.startActivityUncheckedLocked-startActivityLocked

-若找到 resume 状态的 Activity,执行startPausingLocked()暂停该 Activity,同时暂停所有处于后台栈的 Activity,这里一般来说会把桌面,也就是 Launcher 暂停掉。

ActivityStack.resumeTopActivityInnerLocked

-获取要启动的Activity进程信息,若成功,则表示进程已经启动了,通过realStartActivityLocked启动这个 activity;否则,通过 AMS 代理调用 startProcessAsync 去创建进程。前者的条件就是前面所述的目标 APP 已经启动过的情况,后者则是从头开始创建这个 APP 进程。

ActivityStackSupervisor.startSpecificActivity

我们考虑后者的情况,程序将会往下调用startProcessAsync创建新进程:

void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,String hostingType) {try {            ...// 发布消息以启动进程,以避免在持有 ATMS 锁的情况下调用 AMS 可能出现死锁。final Messagem = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,                    isTop, hostingType, activity.intent.getComponent());            mH.sendMessage(m);        } finally {            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);        }    }

startProcessAsync 会通过消息的方式让 ATMS 服务在处理该消息时创建对应的进程,调用目标为ActivityManagerInternal::startProcess

ActivityManagerInternal::startProcess调用ActivityManagerService::startProcessLocked调用ProcessList::startProcessLocked调用ProcessList::startProcess

如果目标进程是 top app,设置 flag 保证启动的最高优先级,并最终在 startProcess 中创建对应的目标进程,也就是 APP 的进程。

在进程创建成功后,将当前进程切换到新进程,并将ActivityThread类加载到新进程,调用ActivityThread.main

1.ActivityThread.main:创建主线程的 Looper 对象,创建ActivityThread对象,ActivityThread.attach()建立 Binder 通道,开启Looper.loop()消息循环

2.ActivityThread.attach:创建ActivityManagerProxy对象,调用基于IActivityManager接口的 Binder 通道ActivityManagerProxy.attachApplication()

public staticvoidmain(String[] args) {        ...//初始化当前进程的 Looper 对象        Looper.prepareMainLooper();        ...        ActivityThread thread = new ActivityThread();//此处创建Application        thread.attach(false, startSeq);if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }if (false) {            Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));        }// 调用 Looper 的 loop 方法开启无限循环。        Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");    }

Looper 会持续从消息队列中获取消息,然后处理指定的任务。其中,attach 函数调用时会发送ATTACH_APPLICATION_TRANSACTION通知 system_server 中的服务。

此时,应用的ActivityThreadApplicationThread已经被创建,并创建了消息循环机制。当调用ActivityThread.attach时,内部会调用ActivityManagerProxy.attachApplication,通过 Binder 来调用 AMS 中的attachApplication函数,此时会把ApplicationThread传递过去。

attachApplication-attachApplicationLocked主要有两个关键函数需要关注:

◆bindApplication

◆ActivityTaskManagerService.LocalService#attachApplication

private booleanattachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {synchronized (mProcLock) {        app.mState.setCurAdj(ProcessList.INVALID_ADJ);        app.mState.setSetAdj(ProcessList.INVALID_ADJ);        app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);        mOomAdjuster.setAttachingSchedGroupLSP(app);        app.mState.setForcingToImportant(null);        updateProcessForegroundLocked(app, false0false);        app.mState.setHasShownUi(false);        app.mState.setCached(false);        app.setDebugging(false);        app.setKilledByAm(false);        app.setKilled(false);        app.setUnlocked(StorageManager.isUserKeyUnlocked(app.userId));    }// 移除进程超时信息    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);final ProviderInfoListproviderList = ProviderInfoList.fromList(providers);if (app.getIsolatedEntryPoint() != null) {        thread.runIsolatedEntryPoint(            app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());    } else if (instr2 != null) {        thread.bindApplication(processName, appInfo,                               app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,                               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,                               app.getStartElapsedTime(), app.getStartUptime());    } else {        thread.bindApplication(processName, appInfo,                               app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,                               providerList, null, profilerInfo, nullnullnull, 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,                               app.getStartElapsedTime(), app.getStartUptime());    }if (normalMode) {try {// 最终调用ActivityTaskManagerService.LocalService#attachApplication()            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());        } catch (Exception e) {        }    }return true;}

我们先关注thread.bindApplication,thread 就是刚刚由新进程传过来的。

函数先调用bindApplication向进程发送H.BIND_APPLICATION命令,进程收到该命令后,通过handleBindApplication处理:

private void handleBindApplication(AppBindData data) {    // 初始化contextfinal ContextImpl appContext = ContextImpl.createAppContext(thisdata.info);       // 初始化Instrumentationif (ii != null) {        initInstrumentation(ii, data, appContext);    } else {        mInstrumentation = new Instrumentation();        mInstrumentation.basicInit(this);    }        Application app; try {// 初始化Application// 调用LoadedApk#makeApplicationInner()        app = data.info.makeApplicationInner(data.restrictedBackupMode, null);                   mInstrumentation.onCreate(data.instrumentationArgs);        // 回调Application#onCreate()        mInstrumentation.callApplicationOnCreate(app);    } finally {    }}

handleBindApplication初始化context,然后初始化Instrumentation对象,创建Application对象,并调用该对象的onCreate

初始化流程调用链为makeApplication-newApplication:

private void handleBindApplication(AppBindData data) {    // 初始化contextfinal ContextImplappContext = ContextImpl.createAppContext(this, data.info);       // 初始化Instrumentationif (ii != null) {        initInstrumentation(ii, data, appContext);    } else {        mInstrumentation = new Instrumentation();        mInstrumentation.basicInit(this);    }        Application app; try {// 初始化Application// 调用LoadedApk#makeApplicationInner()        app = data.info.makeApplicationInner(data.restrictedBackupMode, null);                   mInstrumentation.onCreate(data.instrumentationArgs);        // 回调Application#onCreate()        mInstrumentation.callApplicationOnCreate(app);    } finally {    }}public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication != null) {   return mApplication;    }StringappClass = mApplicationInfo.className;    java.lang.ClassLoadercl = getClassLoader();//此时新建一个 Application 的 ContextImpl 对象,ContextImplappContext = ContextImpl.createAppContext(mActivityThread, this);//通过在 handleBindApplication 创建的 mInstrumentation 对象新建一个 Application 对象,同时进行 attach。    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);    appContext.setOuterContext(app);}public Application newApplication(ClassLoader cl, String className, Context context) {    return newApplication(cl.loadClass(className), context);}Instrumentation类:static public Application newApplication(Class<?> clazz, Context context)  {//实例化 ApplicationApplicationapp = (Application)clazz.newInstance();     // Application 和 context绑定    app.attach(context);    return app;}//attach 就是将新建的 ContextImpl 赋值到 mBase,这个 ContextImpl 对象就是所有Application 内 Context 的具体实现,同时赋值一些其他的信息如 mLoadedApk。final void attach(Context context) {        mBase = base;      mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;}

然后是makeApplicationInner的细节

public Application makeApplicationInner(boolean forceDefaultAppClass,                                        Instrumentation instrumentation) {return makeApplicationInner(forceDefaultAppClass, instrumentation, false);}private Application makeApplicationInner(boolean forceDefaultAppClass,                                         Instrumentation instrumentation, boolean allowDuplicateInstances) {if (mApplication != null) {return mApplication;    }synchronized (sApplications) {final Applicationcached = sApplications.get(mPackageName);if (cached != null) {if (!allowDuplicateInstances) {                mApplication = cached;return cached;            }        }    }Applicationapp =null;final StringmyProcessName = Process.myProcessName();StringappClass = mApplicationInfo.getCustomApplicationClassNameForProcess(        myProcessName);try {final java.lang.ClassLoadercl = getClassLoader();if (!mPackageName.equals("android")) {             initializeJavaContextClassLoader();         }// 初始化Application的上下文ContextImplappContext = ContextImpl.createAppContext(mActivityThread, this);// 创建Application实例        app = mActivityThread.mInstrumentation.newApplication(            cl, appClass, appContext);        appContext.setOuterContext(app);    } catch (Exception e) {    }    mActivityThread.mAllApplications.add(app);    mApplication = app;if (!allowDuplicateInstances) {synchronized (sApplications) {            sApplications.put(mPackageName, app);        }    }if (instrumentation != null) {try {// 回调Application#onCreate()            instrumentation.callApplicationOnCreate(app);        } catch (Exception e) {        }    }return app;}

对于新创建的这个进程而言,当callApplicationOnCreate完成调用以后,这个进程的上下文,以及Application对象和Instrumentation对象都完成的创建和初始化。而在进程这波完成上述的初始化过程中,AMS 那边也没闲着,在发送完相应的命令以后,ActivityManagerService#attachApplicationLocked继续往下调用ActivityTaskManagerService.LocalService#attachApplication

public booleanattachApplication(WindowProcessController wpc) throws RemoteException {synchronized (mGlobalLockWithoutBoost) {try {// 调用RootWindowContainer#attachApplication()// 最终调用AttachApplicationHelper#test()return mRootWindowContainer.attachApplication(wpc);        } finally {                   }    }}public booleantest(ActivityRecord r) {if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard            || r.app != null || mApp.mUid != r.info.applicationInfo.uid            || !mApp.mName.equals(r.processName)) {return false;    }try {// 调用ActivityTaskSupervisor#realStartActivityLocked()if (mTaskSupervisor.realStartActivityLocked(r, mApp,                mTop == r && r.getTask().canBeResumed(r) /* andResume */,true /* checkConfig */)) {            mHasActivityStarted = true;        }    } catch (RemoteException e) {    }return false;}

可以注意到,最终这个函数将往下执行ActivityTaskSupervisor#realStartActivityLocked完成最后的步骤。而如果此前不需要创建新进程,那么刚打开 APP 的时候就会从这个地方开始恢复进程的状态了。

booleanrealStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {            // 创建启动Activity的事务 final ClientTransactionclientTransaction = ClientTransaction.obtain(proc.getThread(), r.token);final booleanisTransitionForward = r.isTransitionForward();final IBinderfragmentToken = r.getTaskFragment().getFragmentToken();// 添加callback    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),                    System.identityHashCode(r), r.info,                                     mergedConfiguration.getGlobalConfiguration(),                    mergedConfiguration.getOverrideConfiguration(), r.compat,                    r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,                    proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),                    results, newIntents, r.takeOptions(), isTransitionForward,                    proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,                    r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));// 设置Activity启动后的生命周期状态final ActivityLifecycleItem lifecycleItem;if (andResume) {// RESUME状态        lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);    } else {// PAUSE状态        lifecycleItem = PauseActivityItem.obtain();    }// 设置状态    clientTransaction.setLifecycleStateRequest(lifecycleItem);// 开启事务,最终调用ClientLifecycleManager#scheduleTransaction()    mService.getLifecycleManager().scheduleTransaction(clientTransaction);                         return true;}

函数首先创建 Activity 事务,设置对应的 callback ,以及对应的生命周期ActivityLifecycleItem,最终开始调度事务lientLifecycleManager#scheduleTransaction

// 启动Activity的事务void scheduleTransaction(ClientTransaction transaction) throws RemoteException {final IApplicationThreadclient = transaction.getClient();// 调用ClientTransaction#schedule()    transaction.schedule(); }public void schedule() throws RemoteException {// 调用ApplicationThread#scheduleTransaction()    mClient.scheduleTransaction(this);}@Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {// 最终调用ClientTransactionHandler#scheduleTransaction()    ActivityThread.this.scheduleTransaction(transaction);}void scheduleTransaction(ClientTransaction transaction) {    transaction.preExecute(this);// 发送消息,在H类中接收消息    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}

可以看到,最终由 AMS 向进程发出H.EXECUTE_TRANSACTION命令,这个命令同样会被进程那边接受并处理:

class H extends Handler {public void handleMessage(Message msg) {switch (msg.what) {case EXECUTE_TRANSACTION:final ClientTransactiontransaction = (ClientTransaction) msg.obj;// 执行事务                mTransactionExecutor.execute(transaction);if (isSystem()) {                    transaction.recycle();                }break;        }    }}
public void execute(ClientTransaction transaction) {// 调用TransactionExecutor#executeCallbacks()executeCallbacks(transaction);// 执行lifecycleStateexecuteLifecycleState(transaction);    mPendingActions.clear();}

这个函数最终会往下调用ClientTransactionHandler#handleLaunchActivity,最为抽象类的方法,实际调用ActivityThread#handleLaunchActivity

public Activity handleLaunchActivity(ActivityClientRecord r,        PendingTransactionActions pendingActions, Intent customIntent) {  // 在创建Activity之前初始化if (ThreadedRenderer.sRendererEnabled            && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {        HardwareRenderer.preload();    }// 获取WMS服务,初始化WindowManager    WindowManagerGlobal.initialize();// GraphicsEnvironment提示一个activity正在进程上启动    GraphicsEnvironment.hintActivityLaunch();// 启动Activity,调用ActivityThread#performLaunchActivity()final Activitya = performLaunchActivity(r, customIntent); return a;}

handleLaunchActivity最终回调目标ActivityonConfigurationChanged,初始化WindowManagerService,调用ActivityThread.performLaunchActivity

ActivityThread.performLaunchActivity() {//类似 Application 的创建过程,通过 classLoader 加载 activity.    activity = mInstrumentation.newActivity(classLoader,                component.getClassName(), r.intent);//因为 Activity 有界面,所以其 Context 是 ContextThemeWrapper 类型,但实现类仍是ContextImpl.Context appContext = createBaseContextForActivity(r, activity);    activity.attach(context,mInstrumentation,application,...);//与 Window 进行关联//调用 activity 的 onCreate()方法。    mInstrumentation.callActivityOnCreate(activity,...)}public void callActivityOnCreate(Activity activity, Bundle icicle) {prePerformCreate(activity);// 调用Activity#performCreate()    activity.performCreate(icicle);postPerformCreate(activity);}

callActivityOnCreate中会回调Activity.performCreate,其中调用ActivityonCreateActivity.setContentViewActivityThread.performResumeActivityperformResumeActivity最终会回调onResume

总之,到这里之后,新应用的进程算是创建完成了。

参考文章(见原文末尾)

Activity 原生启动流程分析

看雪ID:Tokameine

https://bbs.kanxue.com/user-home-924548.htm

*本文为看雪论坛优秀文章,由 Tokameine原创,转载请注明来自看雪社区

#

原文始发于微信公众号(看雪学苑):Activity 原生启动流程分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月11日23:45:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Activity 原生启动流程分析http://cn-sec.com/archives/4155776.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息