美文网首页
Android- Activity的启动过程 (结合Zygote

Android- Activity的启动过程 (结合Zygote

作者: 行走中的3卡 | 来源:发表于2023-07-25 10:20 被阅读0次

以下仅先分析 Activity的启动, 未涉及 App 启动

1. 日志分析

// 先是 start u0调用, 然后再创建 ActivityThread (第一次创建)

07-25  10:55:39.238  D  1879   8353   ActivityTaskManager:                             startActivityAsUser: callingPid=3746, callingUid=10126, caller=com.android.server.wm.ActivityTaskManagerService.startActivityAsUser:1815 com.android.server.wm.ActivityTaskManagerService.startActivity:1766 android.app.IActivityTaskManager$Stub.onTransact:1244 com.android.server.wm.ActivityTaskManagerService.onTransact:6588 android.os.Binder.execTransactInternal:1316 android.os.Binder.execTransact:1280 <bottom of call stack>
07-25  10:55:39.239  I  1879   8353   ActivityTaskManager:                             START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.widgettest/.WidgetMainActivity bnds=[543,1172][789,1510]} from uid 10126

// WindowManager 先进行添加Window ?? -> 对的, 但是 不会 回调 App
Activity.onCreate/onResume/onAttachToWindow/onWindowFocusChange,要ActivityThread创建后才会

07-25  10:55:39.252  V  1879   8353   WindowManager:                                   Added starting ActivityRecord{436ab0 u0 com.example.widgettest/.WidgetMainActivity} t23}: startingWindow=null startingView=com.android.server.wm.StartingSurfaceController$StartingSurface@5e76861
07-25  10:55:39.265  D  1879   3586   ActivityManagerPerformance:                      onActivityResumeLocked() r: com.example.widgettest (ActivityRecord{436ab0 u0 com.example.widgettest/.WidgetMainActivity} t23})
07-25  10:55:39.271  V  1879   4894   WindowManager:                                   addWindow: ActivityRecord{436ab0 u0 com.example.widgettest/.WidgetMainActivity} t23} startingWindow=Window{365c937 u0 Splash Screen com.example.widgettest}
07-25  10:55:39.310  I  3145   3281   ViewRootImpl@94eeaf5[widgettest]:                performTraversals params={(0,0)(fillxfill) sim={adjust=pan} ty=APPLICATION_STARTING fmt=TRANSLUCENT wanim=0x1030309

// fork 进程 771, 调用 Java 层的 进程启动及初始化的操作 => 调用 Zygote 是由 ProcessList 发起的? 需确认

07-25  10:55:39.370  D  1322   1322   Zygote:                                          Forked child process 771
// frameworks/base/services/core/java/com/android/server/am/ProcessList.java
// { private Process.ProcessStartResult startProcess
07-25  10:55:39.370  W  1879   2455   ActivityManager:                                 Slow operation: 98ms so far, now at startProcess: returned from zygote!
// }
// { handleProcessStartedLocked
07-25  10:55:39.370  W  1879   2455   ActivityManager:                                 Slow operation: 98ms so far, now at startProcess: done updating battery stats
07-25  10:55:39.370  W  1879   2455   ActivityManager:                                 Slow operation: 98ms so far, now at startProcess: building log message
07-25  10:55:39.370  I  1879   2455   ActivityManager:                                 Start proc 771:com.example.widgettest/u0a339 for next-top-activity {com.example.widgettest/com.example.widgettest.WidgetMainActivity}
07-25  10:55:39.370  W  1879   2455   ActivityManager:                                 Slow operation: 98ms so far, now at startProcess: starting to update pids map
07-25  10:55:39.371  W  1879   2455   ActivityManager:                                 Slow operation: 98ms so far, now at startProcess: done updating pids map
// handleProcessStartedLocked }

// PID: 771 -> com.example.widgettest (日志右边有注释)

07-25  10:55:39.511  E  771    771    ActivityThread:                                  JustDebugTag main // ActivityThread 主函数入口
07-26  15:47:44.305  E  19988  19988  ActivityThread:                                  java.lang.Exception
07-26  15:47:44.305  E  19988  19988  ActivityThread:                                  at android.app.ActivityThread.main(ActivityThread.java:8708)
07-26  15:47:44.305  E  19988  19988  ActivityThread:                                  at java.lang.reflect.Method.invoke(Native Method)
07-26  15:47:44.305  E  19988  19988  ActivityThread:                                  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) // 反射调用
07-26  15:47:44.305  E  19988  19988  ActivityThread:                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067) // main 方法
07-25  10:55:39.513  E  771    771    ActivityThread:                                  JustDebugTag ApplicationThread create this=android.app.ActivityThread$ApplicationThread@f54e4a5 // 创建 ApplicationThread 静态变量
07-25  10:55:39.513  E  771    771    ActivityThread:                                  JustDebugTag ActivityThread create this=android.app.ActivityThread@16dd07a // 创建 ActivityThread 实例对象 (先创建了它的静态变量 ApplicationThread)
07-25  10:55:39.513  E  771    771    ActivityThread:                                  JustDebugTag attach system=false

2. 关键点

(1)ActivityThread
应用程序进程 的 主线程,管理、调度和执行Activity,广播,以及ActivityManager 请求的其他操作。
(2)ApplicationThread
AMS/PMS 与 ActivityThread 通信的中间者;
它与AMS/PMS 通过Binder 通信,
与 ActivityThread 通过Handler通信 ( ActivityThread实现了ClientTransactionHandler)
(3)AMS/PMS
大管家,协调各应用、组件的交互需求.

3. 启动 Activity 先决条件

(1) 确保已经启动了App (Zygote fork app进程),
(2) 创建了 ActivityThread
(3) 创建了 ApplicationThread (在 new ActivityThread 时创建静态变量), 并将它与 AMS 绑定
(4) AMS/PMS 解析 App 的清单文件,根据 Activity 的属性执行生命周期操作 (通过ApplicationThread 回调到 ActivityThread)
(5) ActivityThread 回调 Activity 的生命周期函数.

下面这个图则是很经典 的:


App Activity 启动框架图.jpg

值得注意的是, 其实 ApplicationThread 是作为 ActivityThread 的内部类实现的

4. ActivityThread 与 AMS 的交互

分两个过程:
(1) ActivityThread.main 函数里创建 ActivityThread 对象,并且创建 ApplicationThread 对象。
然后调用 attach 方法,它里面会调用 AMS.attachApplication, 将自己与 AMS 绑定 (并传递回调接口为 ApplicationThread 对象)

(2) AMS.attachApplication 进行内部处理, 得到应用信息;
然后回调 ApplicationThread.bindApplication(), 将在AMS里得到的应用信息(特别是ApplicationInfo对象 ) 传递给 ActivityThread (Handler)

关键代码如下:
frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    @UnsupportedAppUsage
    final ApplicationThread mAppThread = new ApplicationThread();
    
    public static void main(String[] args) {
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq); 
    }
    
    @UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();             
    }
    
    private class ApplicationThread extends IApplicationThread.Stub {   
        public final void bindApplication(String processName, ApplicationInfo appInfo, ..){
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo; 
            sendMessage(H.BIND_APPLICATION, data);          
        }
    }
    
    class H extends Handler {
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
    }

    @UnsupportedAppUsage
    private void handleBindApplication(AppBindData data) {
    
    }   
}   

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

    @GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }

          ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info;
                thread.bindApplication(processName, appInfo,          
    }

5. AMS 里的进程管理

AMS.attachApplication -> attachApplicationLocked -> updateLruProcessLocked

    @GuardedBy("this")
    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
            ProcessRecord client) {
        mProcessList.updateLruProcessLocked(app, activityChange, client);
    }

其中, mProcessList 是 通过 内部类 Injector.getProcessList 去获取的,
而这 Injector 一般是 AMS 创建时同步创建: mInjector = new Injector(systemContext);
也可以在 测试时 由外部 注入的。

    /**
     * Process management.
     */
    final ProcessList mProcessList;

        mProcessList = mInjector.getProcessList(this);

ProcessList 是 am 下的一个类, 服务于 AMS, 用于管理所有进程。
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
它里面有实现 startProcess, 响应来自 native 层的创建调用

上面的 Injector 其实也是 AMS 的一个内部类 getProcessList 相当于创建一个 ProcessList

    @VisibleForTesting
    public static class Injector {
        ...
        private Context mContext;

        public Injector(Context context) {
            mContext = context;
        }

        public Context getContext() {
            return mContext;
        }

        /**
         * Return the process list instance
         */
        public ProcessList getProcessList(ActivityManagerService service) {
            return new ProcessList();
        }

参考

https://blog.csdn.net/qq_39867049/article/details/130838441
Android App Process 启动流程攻略 - 掘金 (juejin.cn)
(这个讲得很不错)

相关文章

  • Activity启动流程

    Activity启动流程 根Activity启动过程中会涉及4个进程,分别是Zygote进程、Launcher进程...

  • 2018-07-04 activityThread

    Activity的启动过程。 我们知道,在Android系统启动时,第一个启动起来的进程就是zygote进程,然后...

  • Android Framework—SystemServer进程

    zygote进程启动过程 zygote启动过程[https://www.jianshu.com/p/576a265...

  • Android View体系

    一 View的添加过程 先来一张时序图: 上图描述了Activity的启动过程,简言之就是:AMS通知zygote...

  • Zygote进程启动分析

    最近在追溯Activity启动的流程,顺手温习下Android上层的启动流程,就从Zygote进程启动开始。 Zy...

  • Android Framework - ServiceManag

    前言 前面已经分析了 Zygote 进程的启动过程,在 Zygote 启动时,SystemServer 进程也顺带...

  • Activity-创建

    在栈顶Activity执行onPause方法退出后,开始新建Activity。如果APP是首次启动则让Zygote...

  • Android系统流程 v1.3

    Zygote的启动过程 1.系统启动init进程时会启动Zygote进程(负责Android运行时进程和应用进程的...

  • Activity启动流程

    Activity启动流程ActivityThread一个应用对应一个ActivityThread,当Zygote进...

  • Android 四大组件的一些总结

    1.Activity 1.1 Activity的启动流程 先来安利一些知识点: 1.zygote 1、Androi...

网友评论

      本文标题:Android- Activity的启动过程 (结合Zygote

      本文链接:https://www.haomeiwen.com/subject/xfccpdtx.html