美文网首页
从ActivityThread到Application的onCr

从ActivityThread到Application的onCr

作者: 未扬帆的小船 | 来源:发表于2019-11-07 17:15 被阅读0次
    流程图.png

    跟着源码走一遍Application的onCreate()的创建过程,顺便看看这个过程产生什么对象,做了一些什么事情,对流程有个大概的了解过程。有利于编程的时候出现的一些bug处理,面试的时候关于其中一些问题的提问心里也相对比较靠谱点。

    • 从ActivityThread #Main()开始

     public static void main(String[] args) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
            ......
            Process.setArgV0("<pre-initialized>");
            Looper.prepareMainLooper();
            关键代码1
            ActivityThread thread = new ActivityThread();
            thread.attach(false, startSeq);
          关键代码2
            Looper.loop();
    
        }
    

    上面的代码中
    关键代码1先创建ActivityThread对象,再attach()
    关键代码2 Looper.loop() 开始不断的轮询

    面试经常会问,Looper.loop()会阻塞线程,但是为什么主线程这里调用了就不会?

    进入看一下 thread.attach(false, startSeq)

     private void attach(boolean system, long startSeq) {
            sCurrentActivityThread = this;
            mSystemThread = system;
            if (!system) {
                ViewRootImpl.addFirstDrawHandler(new Runnable() {
                    @Override
                    public void run() {
                        ensureJitEnabled();
                    }
                });
                android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                        UserHandle.myUserId());
                RuntimeInit.setApplicationObject(mAppThread.asBinder());
                //关键代码1
                final IActivityManager mgr = ActivityManager.getService();
                try {
              //关键代码2
                    mgr.attachApplication(mAppThread, startSeq);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
                .......
            } else {
                 ......
            }
    
           ......  
    

    关键代码1 创建了mgr这个对象,先看看是什么对象先
    ActivityManager.getService();

        public static IActivityManager getService() {
            return IActivityManagerSingleton.get();
        }
    
        private static final Singleton<IActivityManager> IActivityManagerSingleton =
                new Singleton<IActivityManager>() {
                    @Override
                    protected IActivityManager create() {
                  //关键代码1
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                //关键代码2
                        final IActivityManager am = IActivityManager.Stub.asInterface(b);
                        return am;
                    }
                };
    
    

    关键代码1 中获取到的时候一个IBinder类型的对象,
    关键代码2 绑定到IActivityManager.Stub.asInterface(b)这是AIDL客户端获取服务端的对象,返回的对象是ActivityManagerService属于(system_server进程)的binder进程

    好 现在让我返回上一层看回上个代码的 关键代码2mgr.attachApplication(mAppThread, startSeq);
    先看一下传入的参数 mAppThread什么时候初始化的

    //这里是在 ActivityThread的成员变量位置初始化的
    final ApplicationThread mAppThread = new ApplicationThread();
    private class ApplicationThread extends IApplicationThread.Stub{
      ....
    }
    

    可以看到mAppThreadApplicationThread类型 也是一个binder对象。
    下面看一下attachApplication()方法里写了什么,
    (这里的运行已经是在另外的binder的服务端(ActivityManagerService)而不是在主线程的ActivityThread的线程中)可能是两个不同的进程。

    // ActivityManagerService类
        @Override
        public final void attachApplication(IApplicationThread thread, long startSeq) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();
                final int callingUid = Binder.getCallingUid();
                final long origId = Binder.clearCallingIdentity();
              //关键代码1
                attachApplicationLocked(thread, callingPid, callingUid, startSeq);
                Binder.restoreCallingIdentity(origId);
            }
        }
    

    attachApplicationLocked(thread, callingPid, callingUid, startSeq);

     @GuardedBy("this")
        private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
          ......
      mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
                if (app.isolatedEntryPoint != null) {
                    // This is an isolated process which should just call an entry point instead of
                    // being bound to an application.
                    thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
                } else if (app.instr != null) {
                    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);
                } else {
                    thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                            null, null, null, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, isAutofillCompatEnabled);
                }
       ......
        }
    

    上面又使用了thread对象,切换回 ActivityThread.ApplicaitionThread的进程中去了。也就是返回原来的主线程中了
    进去上面的方法看一下
    thread.bindApplication() ActivityThread.ApplicaitionThread # bindApplication()

     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) {
    
                if (services != null) {
                    if (false) {
                        // Test code to make sure the app could see the passed-in services.
                        for (Object oname : services.keySet()) {
                            if (services.get(oname) == null) {
                                continue; // AM just passed in a null service.
                            }
                            String name = (String) oname;
    
                            // See b/79378449 about the following exemption.
                            switch (name) {
                                case "package":
                                case Context.WINDOW_SERVICE:
                                    continue;
                            }
    
                            if (ServiceManager.getService(name) == null) {
                                Log.wtf(TAG, "Service " + name + " should be accessible by this app");
                            }
                        }
                    }
    
                    // Setup the service cache in the ServiceManager
                    ServiceManager.initServiceCache(services);
                }
    
                setCoreSettings(coreSettings);
    
                AppBindData data = new AppBindData();
                data.processName = processName;
                data.appInfo = appInfo;
                data.providers = providers;
                data.instrumentationName = instrumentationName;
                data.instrumentationArgs = instrumentationArgs;
                data.instrumentationWatcher = instrumentationWatcher;
                data.instrumentationUiAutomationConnection = instrumentationUiConnection;
                data.debugMode = debugMode;
                data.enableBinderTracking = enableBinderTracking;
                data.trackAllocation = trackAllocation;
                data.restrictedBackupMode = isRestrictedBackupMode;
                data.persistent = persistent;
                data.config = config;
                data.compatInfo = compatInfo;
                data.initProfilerInfo = profilerInfo;
                data.buildSerial = buildSerial;
                data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;
              //关键代码1
                sendMessage(H.BIND_APPLICATION, data);
            }
    

    关键代码1 接着进去看 sendMessage(H.BIND_APPLICATION, data);

      void sendMessage(int what, Object obj) {
            sendMessage(what, obj, 0, 0, false);
        }
    
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
            if (DEBUG_MESSAGES) Slog.v(
                TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
                + ": " + arg1 + " / " + obj);
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            if (async) {
                msg.setAsynchronous(true);
            }
    //关键代码1
            mH.sendMessage(msg);
        }
    

    因为上面所用的mHActivityThread的成员变量,所以我们追踪找一下
    handleMessage(Message msg) 所在的位置 ActivityThread.H #handleMessage()

            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;
                       //关键代码1
                        handleBindApplication(data);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
    

    handleBindApplication(data)

    private void handleBindApplication(AppBindData data) {
          ......
            //设置进程名字
            Process.setArgV0(data.processName);
            android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                    UserHandle.myUserId());
            VMRuntime.setProcessPackageName(data.appInfo.packageName);
        ......
    
            if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
                AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
             ......
    // 创建ContextImpl
           final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    
           ......
            Application app;
            final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
            final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
            try {
    
           // data.info的对象是LoadedApk, 通过反射创建目标应用Application对象
                app = data.info.makeApplication(data.restrictedBackupMode, null);
          app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);
                mInitialApplication = app;
          ......
                    mInstrumentation.onCreate(data.instrumentationArgs);
          ......
                    mInstrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                   
                }
            } finally {
             ......
            }
        }
    

    上面的缩减代码中做了部分注释,最终我们跟踪到mInstrumentation.callApplicationOnCreate(app);

        public void callApplicationOnCreate(Application app) {
            app.onCreate();
        }
    

    从上面可以看到Application进入onCreate()方法中,这就是从最开始main()方法开始到最后的Application的onCreate()的创建过程。这个是app程序的创建过程,还是系统程序的创建过程跟这个流程有点相似,可以看一下 gityuan 大神的文章http://gityuan.com/2017/04/02/android-application/

    相关文章

      网友评论

          本文标题:从ActivityThread到Application的onCr

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