从ActivityThread到Application的onCreate的流程

流程图.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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值