美文网首页
Android应用启动的实质(三)

Android应用启动的实质(三)

作者: 榕城歌者 | 来源:发表于2019-06-23 11:32 被阅读0次

    ActivityManagerService在启动应用程序时会检查这个应用程序需要的应用程序进程是否存在,不存在就会请求Zygote进程将需要的应用程序进程启动。调用Zygote的fork方法后,它也会调用Zygote的一系列初始化的方法,新创建的应用程序进程也会创建新的Binder线程池与消息队列。

    源码文件frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
              throws ZygoteInit.MethodAndArgsCaller {
          if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
          Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
          redirectLogStreams();
          commonInit();
          nativeZygoteInit();//1
          applicationInit(targetSdkVersion, argv, classLoader);//2
      }
    

    注释1处会在新创建的应用程序进程中创建Binder线程池.
    注释2其实是在创建并且启动应用程序的主线程,也就是我们常说的UI线程实例ActivityThread

    启动Binder线程池

    Binder是Android系统通信的基础,是Android系统进程间通信(IPC)方式之一。应用启动,Activity的切换是通过ActivityManagerService来调度的,但是又是谁去通知ActivityManagerService去启动新的Activity呢?就是通过Binder去通知ActivityManagerService来调度的。

    支持Binder通信的进程中都有一个ProcessState类,它里面有一个mThreadPoolStarted 变量,来表示Binder线程池是否已经被启动过,默认值为false。在每次调用这个函数时都会先去检查这个标记,从而确保Binder线程池只会被启动一次。如果Binder线程池未被启动则设置mThreadPoolStarted为true,最后调用spawnPooledThread函数来创建线程池中的第一个线程,也就是线程池的main线程。
    源码文件:frameworks/native/libs/binder/ProcessState.cpp

    void ProcessState::startThreadPool()
    {
        AutoMutex _l(mLock);
        if (!mThreadPoolStarted) {
            mThreadPoolStarted = true;
            spawnPooledThread(true);
        }
    }
    
    void ProcessState::spawnPooledThread(bool isMain)
    {
        if (mThreadPoolStarted) {
            String8 name = makeBinderThreadName();
            ALOGV("Spawning new pooled thread, name=%s\n", name.string());
            sp<Thread> t = new PoolThread(isMain);
            t->run(name.string());//1
        }
    }
    

    启动ActivityThread

    回到RuntimeInit.java中的 applicationInit方法

    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
               throws ZygoteInit.MethodAndArgsCaller {
    ...
           final Arguments args;
           try {
               args = new Arguments(argv);
           } catch (IllegalArgumentException ex) {
               Slog.e(TAG, ex.getMessage());       
               return;
           }
           Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
           invokeStaticMain(args.startClass, args.startArgs, classLoader);//1
       }
    

    在applicationInit中会在注释1处调用invokeStaticMain函数,需要注意的是第一个参数args.startClass,就是刚刚谈到的android.app.ActivityThread 。
    继续看invokeStaticMain方法:

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
        try {
            cl = Class.forName(className, true, classLoader);//1
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });//2
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        }
        ...
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);//3
    }
    

    注释1通过反射来获得android.app.ActivityThread类。
    注释2处来获得ActivityThread的main函数,并将main函数传入到注释3处的ZygoteInit中的MethodAndArgsCaller类的构造函数中,最后抛出去。
    从前面可以知道,RuntimeInit类中zygoteInit也会将这个对象继续向上抛出。

    最终在被捕获并且执行
    源码文件frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {
      ...
         try {
            ...
         } catch (MethodAndArgsCaller caller) {
             caller.run();//1
         } catch (RuntimeException ex) {
             Log.e(TAG, "Zygote died with exception", ex);
             closeServerSocket();
             throw ex;
         }
     }
    

    注释1中MethodAndArgsCaller类内部会通过反射调用ActivityThread的main函数。

    来看一下ActivityThread的main的方法都干了什么:
    frameworks/base/core/java/android/app/ActivityThread.java

     public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
            SamplingProfilerIntegration.start();
    ...
            Looper.prepareMainLooper();//1
            ActivityThread thread = new ActivityThread();//2
            thread.attach(false);
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            Looper.loop();//3
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    注释1处在当前应用程序进程中创建消息循环
    注释2处创建ActivityThread
    注释3处调用Looper的loop,使得Looper开始工作,开始处理消息。
    可以看出,系统在应用程序进程启动完成后,就会创建一个消息循环,用来方便的使用Android的消息处理机制。

    讲到这里,新应用启动的前提已经准备好了。

    相关文章

      网友评论

          本文标题:Android应用启动的实质(三)

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