美文网首页
Application启动流程分析(android-28)

Application启动流程分析(android-28)

作者: feifei_fly | 来源:发表于2020-12-08 21:01 被阅读0次

    以android-28为基准,总结了一下Application的启动过程,记录下来,方便以后查阅。

    Application启动流程图

    image

    一、Application启动相关的几个类:

    • ActivityThread:
    • H
    • Instrumentation
    • ApplicationThread
    • ActivityManger
    • ActivityMangerService

    1.1、ActivityThread

    Android application启动的入口类

    1.2、H

    ActivityThread的内部类,是主线程Handler类,负责处理主线程的所有消息,尤其是App,Activity声明周期相关的Message

     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:
                
                        AppBindData data = (AppBindData)msg.obj;
                        handleBindApplication(data);
                    
                        break;
                    case EXIT_APPLICATION:
                        if (mInitialApplication != null) {
                            mInitialApplication.onTerminate();
                        }
                        Looper.myLooper().quit();
                        break;
                    
                }
    

    1.3、Instrumentation

    Instrumentation会在应用程序的任何代码运行之前被实例化,它能够允许你监视应用程序和系统的所有交互。
    

    Instrumentation 是在Application被创建前 创建的,他负责Application、Activity的创建,以及application和Activity的所有生命周期。

    1.4 ApplicationThread

    ApplicationThread 是ActivityThread的内部类,可以视为一个Binder,他的一个重要作用就是,传递给ActivityManagerService,作为ActivityManagerService向当前进程发送消息(IPC)的桥梁

    1.5、 ActivityManger

    和ActivityManagerService IPC 通信的工具,通过它实现当前进程向ActivityManagerService 发送消息(IPC)的功能

     final IActivityManager mgr = ActivityManager.getService();
    
     public static IActivityManager getService() {
            return IActivityManagerSingleton.get();
        }
    
        private static final Singleton<IActivityManager> IActivityManagerSingleton =
                new Singleton<IActivityManager>() {
                    @Override
                    protected IActivityManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                        final IActivityManager am = IActivityManager.Stub.asInterface(b);
                        return am;
                    }
                };
    

    1.6、ActivityMangerService

    ActivityMangerService 系统服务类, 统一管理Android系统中的Application、Activity的创建、启动和声明周期。

    二、Applciation的启动过程

    Application启动的主入口是ActivityThread了的main函数。

    ActivityThread的几个重要属性

    public final class ActivityThread{
         final ApplicationThread mAppThread = new ApplicationThread();
         final Looper mLooper = Looper.myLooper();
          final H mH = new H();
          Instrumentation mInstrumentation;
    }
    
    

    main中的主要操作

     public static void main(String[] args) {
         
           //(1)创建主线程Looper
            Looper.prepareMainLooper();
            //(2) 创建ActivityThread实例,调用attach()方法
             ActivityThread thread = new ActivityThread();
            thread.attach(false, startSeq);
            
            //(3)启动消息循环(主线程死循环)
             Looper.loop();
     }
    

    我们看看thread.attach()方法做了什么

    attach()

    //获取IActivityManager类,可以直接向ActivityManagerService发送IPC消息
     final IActivityManager mgr = ActivityManager.getService();
    
    //向ActivityManagerService发送attachApplication消息
    //另一个关键信息是mAppThread这个参数,将ApplicationThread 对象作为Binder传递给ActvityManagerService  想当前进程发送IPC消息,实现跨进程双向通信。
    mgr.attachApplication(mAppThread, startSeq);
    

    ActivityManagerService

     @Override
        public final void attachApplication(IApplicationThread thread, long startSeq) {
            synchronized (this) {
              ...
                attachApplicationLocked(thread, callingPid, callingUid, startSeq);
                ...
            }
        }
        
        
        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
                ...
        thread.bindApplication(processName, appInfo, providers,
                            app.instr.mClass,
                            profilerInfo, app.instr.mArguments,
                            app.instr.mWatcher,
                            app.instr.mUiAutomationConnection, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, isAutofillCompatEnabled);
                            
                    ...
                }
    
    ActivityManagerService.attachApplication->attachApplicationLocked()->IApplicationThread.bindApplication()
    

    最终调用IApplicationThread.bindApplication,跨进程调用ApplicationThread.bindApplication()

    ApplicationThread.bindApplication()最终向H发送了H.BIND_APPLICATION消息。

     public final void bindApplication(String processName, ApplicationInfo appInfo,
                    List<ProviderInfo> providers, ComponentName instrumentationName,
                    ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                    IInstrumentationWatcher instrumentationWatcher,
                    IUiAutomationConnection instrumentationUiConnection, int debugMode,
                    boolean enableBinderTracking, boolean trackAllocation,
                    boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                    CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                    String buildSerial, boolean autofillCompatibilityEnabled) {
                    
                    ...
                     sendMessage(H.BIND_APPLICATION, data);
                    ...
                    }
    

    H 消息处理

     public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                switch (msg.what) {
                    case BIND_APPLICATION:
                        ...
                        AppBindData data = (AppBindData)msg.obj;
                        handleBindApplication(data);
                        ..
                        break;
                        
                        
                    
                }
    
     private void
        handleBindApplication(AppBindData data) {
            
            
            //(1)创建Instrumentation实例
              final ClassLoader cl = instrContext.getClassLoader();
                    mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentationName.getClassName()).newInstance();
                        
                  
            //(2)创建Application实例            
                app = data.info.makeApplication(data.restrictedBackupMode, null);
    
            //(3)调用callApplicationOnCreate()方法
                mInstrumentation.callApplicationOnCreate(app);
            
        }
    

    data.info 即LoadedApk类,让我们看一下makeApplication做了什么。

      public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
                    ...
                    app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
                        ...
                }
    

    内部也是通过Instrumentation创建的application实例。

    我们再看一下Instrumentation的callApplicationOnCreate方法做了什么。newApplication()实现了Application实例的创建,以及attach()调用;callApplicationOnCreate()中实现了Application.onCreate()的调用。

    Instrumentation.java

    //(1)newApplication 完成了application实例的创建和attach()
    public Application newApplication(ClassLoader cl, String className, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = getFactory(context.getPackageName())
                    .instantiateApplication(cl, className);
            app.attach(context);
            return app;
        }
        
        //(2)
         public void callApplicationOnCreate(Application app) {
            app.onCreate();
        }
    

    至此 就实现了Application类的创建,onAttach()、onCreate()声明周期的回调

    三、参考文章

    https://www.jianshu.com/p/9ecea420eb52

    相关文章

      网友评论

          本文标题:Application启动流程分析(android-28)

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