美文网首页
App启动流程

App启动流程

作者: 天上飘的是浮云 | 来源:发表于2021-11-04 22:19 被阅读0次

    一、先简单介绍下点击手机桌面(也就是Launcher界面)点击某个App的启动过程

    App启动过程.png App启动过程.png 应用启动整体概念.png 应用程序启动涉及的进程间通信.png

    从上面的几个图我们也可以清晰的看到

    1、首先点击Launcher中的某个App,会调用startActivity,它通过binder进程间通信与AMS进行通信,AMS通过socket与Zygote进程通信,请求fork孵化出APP进程即会调用ActivityThread.main()方法。 这就是基本流程

    二、分析源码ActivityThread如何实例化Application和MainActivity的

    2.1 ActivityThread.java中的main()方法

    这里需要注意的是创建了MainLooper, 并使其loop()轮询事件,而且还实例化了ActivityThread,并调用器attach方法

            Looper.prepareMainLooper();
    
            ...
            ActivityThread thread = new ActivityThread();
            thread.attach(false, startSeq);
    
            ...
            Looper.loop();
    

    attach()方法

     private void attach(boolean system, long startSeq) {
    final IActivityManager mgr = ActivityManager.getService();
                try {
    7080行                mgr.attachApplication(mAppThread, startSeq);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
      ...
    }
    
    2.2 在attch方法中又调用了ActivityManagerService.attachApplication方法,在attachApplication方法中又调用了attachApplicationLocked()方法

    在该方法中又通过thread(即ApplicationThread)(ApplicationThread又是ActivityThread的子类)又回调了bindApplication()方法

        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
    
    5049行 thread.bindApplication(processName, appInfo, providers,
                        ...);
    
    ...
    5101行
    // See if the top visible activity is waiting to run in this process...
            if (normalMode) {
                try {
                    didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
            }
    
    
    2.3 在ActivityThread中的bindApplication()中将传回的数据封装为AppBindData实列,并发送了一个H.BIND_APPLICATION Handler消息。

    在Hanlder接受消息的地方又调用了handleBindApplication(data)方法。

    6122行 private void handleBindApplication(AppBindData data) {
    ...
    
    6431行 app = data.info.makeApplication(data.restrictedBackupMode, null);
                    6460行 mInstrumentation.callApplicationOnCreate(app);
    ...
    }
    

    6431行通过LoaderApk.makeApplication反射创建Application实例

                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
    

    6460行通过Instrumentation.callApplicationOnCreate调用onCreate()方法

    2.4 到这里Application已经创建完成了,接着需要创建第一个Activity,y也就是主Activity

    回到2.2, 在ActivityManagerService.attachApplicationLocked()中的5101行,又调用了mAtmInternal.attachApplication

    而mAtmInternal是ActivityTaskManagerInternal,它是个抽象类,真正实现在ActivityTaskManagerService中,而ActivityTaskManagerService.attachApplication方法又调用了

    RootActivityContainer.attachApplication方法

    ActivityTaskManagerService.java
    
            public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
                synchronized (mGlobalLockWithoutBoost) {
                    return mRootActivityContainer.attachApplication(wpc);
                }
            }
    
    2.5 在RootActivityContainer.attachApplication方法中,会从AndroidMainfest.xml解析的Activity信息栈中获取到第一个activity,即为主Activity。
    boolean attachApplication(WindowProcessController app) throws RemoteException {
    ...
                final ActivityRecord top = stack.topRunningActivityLocked();
                  
                    for (int i = 0; i < size; i++) {
                        final ActivityRecord activity = mTmpActivityList.get(i);
                        if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                                && processName.equals(activity.processName)) {
                            try {
    783行                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                        top == activity /* andResume */, true /* checkConfig */)) {
                                    didSomething = true;
                                }
                            } catch (RemoteException e) {
                                Slog.w(TAG, "Exception in new application when starting activity "
                                        + top.intent.getComponent().flattenToShortString(), e);
                                throw e;
                            }
                        }
                    }
    ...
    }
    

    783行,判断如果Activity是主Actiivty就开始进行实例,其实后面的流程和《App startActivity启动流程(AMS)》一致,这里就略过了。

    相关文章

      网友评论

          本文标题:App启动流程

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