Android源碼解析:Application的onCreate()方法是如何被調用的.md

帶着疑問看源碼1bash

1.一個程序的入口是main方法,而當咱們接觸安卓的時候都是Activity的各類生命週期方法,那main在哪裏調用呢?就是ActivityThread中,該類也表明應用程序的主進程.app

ActivityThread 
    -> main()
    public static void main(String[] args) {
        //... 1.開啓Looper
        Looper.prepareMainLooper();

        //2.實例化ActivityThread,並調用attach()方法
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
    
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        //...
        Looper.loop();
    }

    ->attach(false)方法
    private void attach(boolean system) {
        if (!system) {
            //...
            //1.內部調用者的是AMS,將ApplicationThread對象與AMS聯繫起來,ApplicationThread做爲AMS的代理類
            //調用AMS的attachApplication()方法,最後仍是調用到ApplicationThread的bindApplication()方法
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread); //
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // ...
        }else{
             // ...
        }
    
    ApplicationThread.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) {
            //...
            AppBindData data = new AppBindData();
            //...1.數據封裝爲AppBindData,而後發送通知
            sendMessage(H.BIND_APPLICATION, data);
        }

    H接收到消息,而後進行處理,最後會調用ActivityThread的handleBindApplication()
    case BIND_APPLICATION:
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
         AppBindData data = (AppBindData)msg.obj;
         handleBindApplication(data);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;

複製代碼

2.ActivityManager.getService()ide

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

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

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //1.Binder通訊
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
複製代碼

3.handleBindApplication()oop

private void handleBindApplication(AppBindData data) {
        // 將UI線程註冊爲運行時的敏感線程。
        VMRuntime.registerSensitiveThread();
         //...

        //1.建立上下文
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        updateLocaleListFromAppContext(appContext,
                mResourcesManager.getConfiguration().getLocales());
        //...
        // Continue loading instrumentation.
        if (ii != null) {
            final ApplicationInfo instrApp = new ApplicationInfo();
            ii.copyTo(instrApp);
            instrApp.initForUser(UserHandle.myUserId());
            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

            try {
                //2.反射建立Instrumentation實例
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
                throw new RuntimeException(
                    "Unable to instantiate instrumentation "
                    + data.instrumentationName + ": " + e.toString(), e);
            }

            //3.new出組件名稱
            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

            if (mProfiler.profileFile != null && !ii.handleProfiling
                    && mProfiler.profileFd == null) {
                mProfiler.handlingProfiling = true;
                final File file = new File(mProfiler.profileFile);
                file.getParentFile().mkdirs();
                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
            }
        } else {
            mInstrumentation = new Instrumentation();
        }

        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
        } else {
            // Small heap, clamp to the current growth limit and let the heap release
            // pages after the growth limit to the non growth limit capacity. b/18387825
            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
        }

        // Allow disk access during application and provider setup. This could
        // block processing ordered broadcasts, but later processing would
        // probably end up doing the same disk access.
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        try {
            //4.最後也是經過Instrumentation類,發射出ApplicationThread實例
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

            // don't bring up providers in restricted mode; they may depend on the // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                    // For process that contains content providers, we want to
                    // ensure that the JIT is enabled "at some point".
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }

            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing. try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { throw new RuntimeException( "Exception thrown in onCreate() of " + data.instrumentationName + ": " + e.toString(), e); } try { //5.調用Application的onCreate()方法 mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } finally { StrictMode.setThreadPolicy(savedPolicy); } //... } 複製代碼

4.調用時序圖ui

相關文章
相關標籤/搜索