美文网首页
一、App(Activity)启动流程

一、App(Activity)启动流程

作者: HungerDeng | 来源:发表于2018-10-10 17:34 被阅读0次

    理论知识

    1. 涉及进程

    1.1 zygote

    在Android系统里面,zygote是一个进程的名字。Android是基于Linux系统的,当手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux 系统里面,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。
    为了实现资源共用和更快的启动速度,Android系统开启新进程的方式是:fork zygote进程实现的。所以,其他应用所在的进程都是zygote进程的子进程

    1.2 SystemServer

    也是一个进程,是由zygote进程fork出来的。是Android Framework里面两大非常重要的进程之一(SystemServer和zygote进程)。系统里面重要的服务都是在这个进程里面开启的,比如:
    ActivityManagerService、PackageManagerService、WindowManagerService等等。

    在zygote开启的时候,会调用ZygoteInit.main()进行初始化。

    public static void main(String argv[]) {
    
         ...
    
        //在加载首个zygote的时候,会传入初始化参数,使得startSystemServer = true
         boolean startSystemServer = false;
         for (int i = 1; i < argv.length; i++) {
                    if ("start-system-server".equals(argv[i])) {
                        startSystemServer = true;
                    } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                        abiList = argv[i].substring(ABI_LIST_ARG.length());
                    } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                        socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                    } else {
                        throw new RuntimeException("Unknown command line argument: " + argv[i]);
                    }
                }
    
                ...
    
             //开始fork我们的SystemServer进程
         if (startSystemServer) {
                    startSystemServer(abiList, socketName);
             }
    
         ...
    }
    
        private static boolean startSystemServer(String abiList, String socketName)
                throws MethodAndArgsCaller, RuntimeException {
    
             ...
            int pid;
            try {
                ...
                /* Request to fork the system server process,这里 fork出systemServer */
                pid = Zygote.forkSystemServer(
                        parsedArgs.uid, parsedArgs.gid,
                        parsedArgs.gids,
                        parsedArgs.debugFlags,
                        null,
                        parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
    
            /* For child process */
            if (pid == 0) {
                if (hasSecondZygote(abiList)) {
                    waitForSecondaryZygote(socketName);
                }
    
                handleSystemServerProcess(parsedArgs);
            }
    
            return true;
        }
    

    那上面提到的ActivityManagerService、PackageManagerService、WindowManagerService等重要服务,是什么时候在SystemServer进程开启的?

    public final class SystemServer {
    
        //zygote的主入口
        public static void main(String[] args) {
            new SystemServer().run();
        }
    
        private void run() {
    
            ...
            //开启服务
            try {
                startBootstrapServices();
                startCoreServices();
                startOtherServices();
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            }
            ...
        }
    
        ...
    }
    

    显然,在SystemServer进程开启的时候,就会初始化ActivityManagerService等重要服务。

    1.3 Launcher

    其实每一个App其实都是:1. 一个单独的dalvik虚拟机 2. 一个单独的进程
    Launcher本质上也是一个App,也是继承自Activity。我们点击手机桌面上的图标就是Launcher相应不同的点击事件,startActivity不同的Activity而已。所以它也占一个进程。

    1.4 应用进程

    就是你要打开的App所在的进程,在桌面点击应用图标打开应用时,如果应用进程不存在会先创建。是应用的主线程(新创建的进程就是主线程),处理组件生命周期、界面绘制等相关事情。


    2. 涉及对象概念

    • Instrumentation: 每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。是完成对Application和Activity初始化和生命周期调用的工具类。

    • ActivityManagerService(AMS):服务端对象,负责系统中所有Activity的生命周期。

    • ActivityStarter:Activity启动的控制器,处理Intent与Flag对Activity启动的影响,主要功能是:1. 寻找符合启动条件的Activity,如果有多个,让用户选择;2. 校验启动参数的合法性; 3. 返回int参数,代表Activity是否启动成功。

    • ActivityStack:用来管理任务栈里的Activity。
    • ActivityRecord:ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。
    • ActivityStackSupervisior:这是高版本才有的类,它用来管理多个ActivityStack。早期的版本只有一个ActivityStack对应着手机屏幕,后来高版本支持多屏以后,就有了多个ActivityStack,于是就引入了ActivityStackSupervisior用来管理多个ActivityStack。
    • ActivityThread:App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作
    • ApplicationThread:ActivityThread的内部类,用来实现AMS与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。

    Activity的启动流程源码分析请看:Activity启动流程(基于Android26)

    Activity的启动流程时序图(对着上面的概念去理解时序图):

    启动流程时序图

    我们可以来分析 handleLaunchActivity 之后的内容:

    private void handleLaunchActivity() {
        ...
        // 执行启动 Activity
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
            ...
            // resume activity
            handleResumeActivity(r.token, false, r.isForward,
                        !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        } else {
            ...
        }
    }
    
        private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            // 1. 从ActivityClientRecord 中获取待启动的Activity的组件信息
            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);
            }
    
            // 2. 通过Instrumentation的newActivity方法使用类加载器创建Activity对象
            ContextImpl appContext = createBaseContextForActivity(r);
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                ...
            } catch (Exception e) {
               ...
            }        
    
    
            try {
                // 3. makeApplication尝试创建Application
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
          
    
                if (activity != null) {
                    ...
                    // 4. 通过Activity的attach方法来完成一些重要数据的初始化
                    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);
    
                    ...
                    // 5. 通过Instrumentation调用Activity的onCreate方法,这意味着Activity已经完成了整个启动过程
                    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;
                    r.stopped = true;
    
                    // 6. Activity onStart
                    if (!r.activity.mFinished) {
                        activity.performStart();
                        r.stopped = false;
                    }
                    // 7. 通过 Instrumentation 执行 Activity onRestoreInstanceState
                    if (!r.activity.mFinished) {
                        if (r.isPersistable()) {
                            if (r.state != null || r.persistentState != null) {
                                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                        r.persistentState);
                            }
                        } else if (r.state != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                        }
                    }
                    // 8. 通过 Instrumentation 执行 Activity onPostCreate
                    if (!r.activity.mFinished) {
                        activity.mCalled = false;
                        if (r.isPersistable()) {
                            mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                    r.persistentState);
                        } else {
                            mInstrumentation.callActivityOnPostCreate(activity, r.state);
                        }
                        ...
                    }
                }
                r.paused = true;
                mActivities.put(r.token, r);
    
            } catch () {
               ...
            } 
    
            return activity;
        }
    
    -> Activity.java
        final void performCreate(Bundle icicle) {
            ...
            onCreate(icicle);
            ...
        }
    
        final void performStart() {
            ...
            mInstrumentation.callActivityOnStart(this);
            ...
        }
    
    • Activity的attach中,还会完成Window的创建并建立自己和Window的关联,这样当Window接收到外部输入事件后就可以将事件传递给Activity
      关于Activity的Window的创建过程,可以参考:二、Activity的Window创建过程与关联View
    • 想获取某个view的宽高信息,必须在view绘制完成后。如果在onCreate方法里面getWidth(),getHight()得到都为0,这个时候可以利用onPostCreate方法。它是onCreate方法彻底执行完毕的回调。现在知道的做法也就只有在使用ActionBarDrawerToggle的使用在onPostCreate需要在屏幕旋转时候等同步下状态,Google官方提供的实例如下:
    @Overrideprotected void onPostCreate(Bundle savedInstanceState) {    
            super.onPostCreate(savedInstanceState);     
            // Sync the toggle state after onRestoreInstanceState has occurred.    
            mDrawerToggle.syncState();
    }
    

    总体上来说就是在performLaunchActivity方法里面完成了Activity的创建、初始化等。
    接下来就会在handleLaunchActivity方法里面调用handleResumeActivity。

    整个流程可以概括如下:


    image.png

    总结

    App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。
    AMS负责系统中所有Activity的生命周期,因为所有的Activity的开启、暂停、关闭都需要AMS来控制。


    参考:
    Activity启动过程全解析
    一个APP从启动到主页面显示经历了哪些过程?

    相关文章

      网友评论

          本文标题:一、App(Activity)启动流程

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