美文网首页
第一篇:Application启动流程分析

第一篇:Application启动流程分析

作者: feifei_fly | 来源:发表于2019-07-29 17:15 被阅读0次

    一、Application启动过程分析:

    一个app启动的入口就是这个ActivityThread,ctivityThread方法有一个main方法,就是程序的入口了。

    public final class ActivityThread {
    final ApplicationThread mAppThread = new ApplicationThread();
     final ApplicationThread mAppThread = new ApplicationThread();
    final Looper mLooper = Looper.myLooper();
    final H mH = new H();
    
    
    public static void main(String[] args) {
    6084        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    6085        SamplingProfilerIntegration.start();
    6086
    6087        // CloseGuard defaults to true and can be quite spammy.  We
    6088        // disable it here, but selectively enable it later (via
    6089        // StrictMode) on debug builds, but using DropBox, not logs.
    6090        CloseGuard.setEnabled(false);
    6091
    6092        Environment.initForCurrentUser();
    6093
    6094        // Set the reporter for event logging in libcore
    6095        EventLogger.setReporter(new EventLoggingReporter());
    6096
    6097        // Make sure TrustedCertificateStore looks in the right place for CA certificates
    6098        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    6099        TrustedCertificateStore.setDefaultUserDirectory(configDir);
    6100
    6101        Process.setArgV0("<pre-initialized>");
    6102
                //(1)初始化主线程的Looper
    6103        Looper.prepareMainLooper();
    6104
                //(2)创建一个ActivityThread对象
    6105        ActivityThread thread = new ActivityThread();
                //(3)调用attach()方法
    6106        thread.attach(false);
    6107
                //获取 ActivityThread.mH Handler
    6108        if (sMainThreadHandler == null) {
    6109            sMainThreadHandler = thread.getHandler();
    6110        }
    6111
    6112        if (false) {
    6113            Looper.myLooper().setMessageLogging(new
    6114                    LogPrinter(Log.DEBUG, "ActivityThread"));
    6115        }
    6116
    6117        // End of event ActivityThreadMain.
    6118        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                //(4线程 loop开启消息循环。
    6119        Looper.loop();
    6120
    6121        throw new RuntimeException("Main thread loop unexpectedly exited");
    6122    }
    6123}
    }
    

    ActivityThread的main方法,主要做了一下几件事情:

    1、初始化主线程Looper

    //(1)初始化主线程的Looper
    6103        Looper.prepareMainLooper();
    

    2、创建一个ActivityThread实例

     //(2)创建一个ActivityThread对象
    6105        ActivityThread thread = new ActivityThread();
    

    3、调用ActivityThread.attach()方法

     //(3)调用attach()方法
    6106        thread.attach(false);
    

    4、Loop.loop() 消息无限循环。

    其中 主要的操作在 thread.attach(false);中。

     private void attach(boolean system) {
                //初始化sCurrentActivityThread 实例
    5931        sCurrentActivityThread = this;
    5932        mSystemThread = system;
    5933        if (!system) {
    5934      
    5940            
    5943            final IActivityManager mgr = ActivityManagerNative.getDefault();
    5944            try {
    5945                mgr.attachApplication(mAppThread);
    5946            } catch (RemoteException ex) {
    5947                throw ex.rethrowFromSystemServer();
    5948            }
    5949            
    5971        } else {
    5972            
    5976            try {
    5977                mInstrumentation = new Instrumentation();
    5978                ContextImpl context = ContextImpl.createAppContext(
    5979                        this, getSystemContext().mPackageInfo);
    5980                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    5981                mInitialApplication.onCreate();
    5982            } catch (Exception e) {
    5983                throw new RuntimeException(
    5984                        "Unable to instantiate Application():" + e.toString(), e);
    5985            }
    5986        }
    5987
    6019  
    6020    }
    6021
    

    attach中的主要操作为绑定Application的操作

      final IActivityManager mgr = ActivityManagerNative.getDefault();
    5944            try {
    5945                mgr.attachApplication(mAppThread);
    5946            } catch (RemoteException ex) {
    5947                throw ex.rethrowFromSystemServer();
    5948            }
    

    通过Bind 机制,最终会调用ActivityManagerService(AMS)中的
    attachApplication()方法

    public final class ActivityManagerService extends ActivityManagerNative{
      @Override
    6667    public final void attachApplication(IApplicationThread thread) {
    6668        synchronized (this) {
    6669            int callingPid = Binder.getCallingPid();
    6670            final long origId = Binder.clearCallingIdentity();
    6671            attachApplicationLocked(thread, callingPid);
    6672            Binder.restoreCallingIdentity(origId);
    6673        }
    6674    }
    }
    

    attachApplication()方法中 主要调用了attachApplicationLocked()方法。我们接着看AMS中attachApplicationLocked 做了哪些事情:

    
    6431    private final boolean attachApplicationLocked(IApplicationThread thread,
    6432            int pid) {
    6433
    6434        // Find the application record that is being attached...  either via
    6435        // the pid if we are running in multiple processes, or just pull the
    6436        // next app record if we are emulating process with anonymous threads.
    6437        ProcessRecord app;
    6438        if (pid != MY_PID && pid >= 0) {
    6439            synchronized (mPidsSelfLocked) {
    6440                app = mPidsSelfLocked.get(pid);
    6441            }
    6442        } else {
    6443            app = null;
    6444        }
    6445
    6446        if (app == null) {
    6447            Slog.w(TAG, "No pending application record for pid " + pid
    6448                    + " (IApplicationThread " + thread + "); dropping process");
    6449            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
    6450            if (pid > 0 && pid != MY_PID) {
    6451                Process.killProcessQuiet(pid);
    6452                //TODO: killProcessGroup(app.info.uid, pid);
    6453            } else {
    6454                try {
    6455                    thread.scheduleExit();
    6456                } catch (Exception e) {
    6457                    // Ignore exceptions.
    6458                }
    6459            }
    6460            return false;
    6461        }
    6462
    6463        // If this application record is still attached to a previous
    6464        // process, clean it up now.
    6465        if (app.thread != null) {
    6466            handleAppDiedLocked(app, true, true);
    6467        }
    6468
    6469        // Tell the process all about itself.
    6470
    6471        if (DEBUG_ALL) Slog.v(
    6472                TAG, "Binding process pid " + pid + " to record " + app);
    6473
    6474        final String processName = app.processName;
    6475        try {
    6476            AppDeathRecipient adr = new AppDeathRecipient(
    6477                    app, pid, thread);
    6478            thread.asBinder().linkToDeath(adr, 0);
    6479            app.deathRecipient = adr;
    6480        } catch (RemoteException e) {
    6481            app.resetPackageList(mProcessStats);
    6482            startProcessLocked(app, "link fail", processName);
    6483            return false;
    6484        }
    6485
    6486        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
    6487
    6488        app.makeActive(thread, mProcessStats);
    6489        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
    6490        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
    6491        app.forcingToForeground = null;
    6492        updateProcessForegroundLocked(app, false, false);
    6493        app.hasShownUi = false;
    6494        app.debugging = false;
    6495        app.cached = false;
    6496        app.killedByAm = false;
    6497
    6498        // We carefully use the same state that PackageManager uses for
    6499        // filtering, since we use this flag to decide if we need to install
    6500        // providers when user is unlocked later
    6501        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
    6502
    6503        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    6504
    6505        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    6506        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
    6507
    6508        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
    6509            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
    6510            msg.obj = app;
    6511            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
    6512        }
    6513
    6514        if (!normalMode) {
    6515            Slog.i(TAG, "Launching preboot mode app: " + app);
    6516        }
    6517
    6518        if (DEBUG_ALL) Slog.v(
    6519            TAG, "New app record " + app
    6520            + " thread=" + thread.asBinder() + " pid=" + pid);
    6521        try {
    6522            int testMode = IApplicationThread.DEBUG_OFF;
    6523            if (mDebugApp != null && mDebugApp.equals(processName)) {
    6524                testMode = mWaitForDebugger
    6525                    ? IApplicationThread.DEBUG_WAIT
    6526                    : IApplicationThread.DEBUG_ON;
    6527                app.debugging = true;
    6528                if (mDebugTransient) {
    6529                    mDebugApp = mOrigDebugApp;
    6530                    mWaitForDebugger = mOrigWaitForDebugger;
    6531                }
    6532            }
    6533            String profileFile = app.instrumentationProfileFile;
    6534            ParcelFileDescriptor profileFd = null;
    6535            int samplingInterval = 0;
    6536            boolean profileAutoStop = false;
    6537            if (mProfileApp != null && mProfileApp.equals(processName)) {
    6538                mProfileProc = app;
    6539                profileFile = mProfileFile;
    6540                profileFd = mProfileFd;
    6541                samplingInterval = mSamplingInterval;
    6542                profileAutoStop = mAutoStopProfiler;
    6543            }
    6544            boolean enableTrackAllocation = false;
    6545            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
    6546                enableTrackAllocation = true;
    6547                mTrackAllocationApp = null;
    6548            }
    6549
    6550            // If the app is being launched for restore or full backup, set it up specially
    6551            boolean isRestrictedBackupMode = false;
    6552            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
    6553                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
    6554                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
    6555                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
    6556                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
    6557            }
    6558
    6559            if (app.instrumentationClass != null) {
    6560                notifyPackageUse(app.instrumentationClass.getPackageName(),
    6561                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
    6562            }
    6563            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
    6564                    + processName + " with config " + mConfiguration);
    6565            ApplicationInfo appInfo = app.instrumentationInfo != null
    6566                    ? app.instrumentationInfo : app.info;
    6567            app.compat = compatibilityInfoForPackageLocked(appInfo);
    6568            if (profileFd != null) {
    6569                profileFd = profileFd.dup();
    6570            }
    6571            ProfilerInfo profilerInfo = profileFile == null ? null
    6572                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
    6573            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
    6574                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
    6575                    app.instrumentationUiAutomationConnection, testMode,
    6576                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
    6577                    isRestrictedBackupMode || !normalMode, app.persistent,
    6578                    new Configuration(mConfiguration), app.compat,
    6579                    getCommonServicesLocked(app.isolated),
    6580                    mCoreSettingsObserver.getCoreSettingsLocked());
    6581            updateLruProcessLocked(app, false, null);
    6582            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    6583        } catch (Exception e) {
    6584            // todo: Yikes!  What should we do?  For now we will try to
    6585            // start another process, but that could easily get us in
    6586            // an infinite loop of restarting processes...
    6587            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
    6588
    6589            app.resetPackageList(mProcessStats);
    6590            app.unlinkDeathRecipient();
    6591            startProcessLocked(app, "bind fail", processName);
    6592            return false;
    6593        }
    6594
    6595        // Remove this record from the list of starting applications.
    6596        mPersistentStartingProcesses.remove(app);
    6597        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
    6598                "Attach application locked removing on hold: " + app);
    6599        mProcessesOnHold.remove(app);
    6600
    6601        boolean badApp = false;
    6602        boolean didSomething = false;
    6603
    6604        // See if the top visible activity is waiting to run in this process...
    6605        if (normalMode) {
    6606            try {
    6607                if (mStackSupervisor.attachApplicationLocked(app)) {
    6608                    didSomething = true;
    6609                }
    6610            } catch (Exception e) {
    6611                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
    6612                badApp = true;
    6613            }
    6614        }
    6615
    6616        // Find any services that should be running in this process...
    6617        if (!badApp) {
    6618            try {
    6619                didSomething |= mServices.attachApplicationLocked(app, processName);
    6620            } catch (Exception e) {
    6621                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
    6622                badApp = true;
    6623            }
    6624        }
    6625
    6626        // Check if a next-broadcast receiver is in this process...
    6627        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
    6628            try {
    6629                didSomething |= sendPendingBroadcastsLocked(app);
    6630            } catch (Exception e) {
    6631                // If the app died trying to launch the receiver we declare it 'bad'
    6632                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
    6633                badApp = true;
    6634            }
    6635        }
    6636
    6637        // Check whether the next backup agent is in this process...
    6638        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
    6639            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
    6640                    "New app is backup target, launching agent for " + app);
    6641            notifyPackageUse(mBackupTarget.appInfo.packageName,
    6642                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
    6643            try {
    6644                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
    6645                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
    6646                        mBackupTarget.backupMode);
    6647            } catch (Exception e) {
    6648                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
    6649                badApp = true;
    6650            }
    6651        }
    6652
    6653        if (badApp) {
    6654            app.kill("error during init", true);
    6655            handleAppDiedLocked(app, false, true);
    6656            return false;
    6657        }
    6658
    6659        if (!didSomething) {
    6660            updateOomAdjLocked();
    6661        }
    6662
    6663        return true;
    6664    }
    

    核心方法是ApplicationThread中的bindApplication()方法,如下:

     thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
    6574                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
    6575                    app.instrumentationUiAutomationConnection, testMode,
    6576                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
    6577                    isRestrictedBackupMode || !normalMode, app.persistent,
    6578                    new Configuration(mConfiguration), app.compat,
    6579                    getCommonServicesLocked(app.isolated),
    6580                    mCoreSettingsObserver.getCoreSettingsLocked());
    6581            updateLruProcessLocked(app, false, null);
    

    我们知道ApplicationThread是ActivityThread的一个内部类

    
    647    private class ApplicationThread extends ApplicationThreadNative {
    648        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
    649
    650        private int mLastProcessState = -1;
    651
    public final void bindApplication(String processName, ApplicationInfo appInfo,
    853                List<ProviderInfo> providers, ComponentName instrumentationName,
    854                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
    855                IInstrumentationWatcher instrumentationWatcher,
    856                IUiAutomationConnection instrumentationUiConnection, int debugMode,
    857                boolean enableBinderTracking, boolean trackAllocation,
    858                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
    859                CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {
    860
    861            if (services != null) {
    862                // Setup the service cache in the ServiceManager
    863                ServiceManager.initServiceCache(services);
    864            }
    865
    866            setCoreSettings(coreSettings);
    867
    868            AppBindData data = new AppBindData();
    869            data.processName = processName;
    870            data.appInfo = appInfo;
    871            data.providers = providers;
    872            data.instrumentationName = instrumentationName;
    873            data.instrumentationArgs = instrumentationArgs;
    874            data.instrumentationWatcher = instrumentationWatcher;
    875            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    876            data.debugMode = debugMode;
    877            data.enableBinderTracking = enableBinderTracking;
    878            data.trackAllocation = trackAllocation;
    879            data.restrictedBackupMode = isRestrictedBackupMode;
    880            data.persistent = persistent;
    881            data.config = config;
    882            data.compatInfo = compatInfo;
    883            data.initProfilerInfo = profilerInfo;
    884            sendMessage(H.BIND_APPLICATION, data);
    885        }
    709}
    

    bindApplication中 做了一些参数的复制操作到AppBindData参数,最终要的是最后一句话 sendMessage(H.BIND_APPLICATION, data); 最终向ActivityThread中的H Handler发送了一个消息。

    private class H extends Handler {
        
         public void handleMessage(Message msg) {
              case BIND_APPLICATION:
    1543                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
    1544                    AppBindData data = (AppBindData)msg.obj;
    1545                    handleBindApplication(data);
    1546                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    1547                    break;
         }
    }
    

    我们来看一下handleBindApplication 做了哪些事情

     private void handleBindApplication(AppBindData data) {
    // Instrumentation info affects the class loader, so load it before
    5272        // setting up the app context.
    5273        final InstrumentationInfo ii;
    5274     
    5293
    5294        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    5
    5320
    5327//通过反射初始化一个Instrumentation仪表。
    5328        // Continue loading instrumentation.
    5329   
    5330            final ApplicationInfo instrApp = new ApplicationInfo();
    5331            ii.copyTo(instrApp);
    5332            instrApp.initForUser(UserHandle.myUserId());
    5333            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
    5334                    appContext.getClassLoader(), false, true, false);
    5335            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
    5336
    5337            try {
    5338                final ClassLoader cl = instrContext.getClassLoader();
    5339                mInstrumentation = (Instrumentation)
    5340                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    5341            } catch (Exception e) {
    5342                throw new RuntimeException(
    5343                    "Unable to instantiate instrumentation "
    5344                    + data.instrumentationName + ": " + e.toString(), e);
    5345            }
    5346
    5347            final ComponentName component = new ComponentName(ii.packageName, ii.name);
    5348            mInstrumentation.init(this, instrContext, appContext, component,
    5349                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    5350
    5351           //通过LoadedApp命令创建Application实例
    5361    // If the app is being launched for full backup or restore, bring it up in
    5376            // a restricted environment with the base application class.
    5377            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    5378            mInitialApplication = app;
    5379
    5380            // don't bring up providers in restricted mode; they may depend on the
    5381           
    5390
    5391            // Do this after providers, since instrumentation tests generally start their
    5392            // test thread at this point, and we don't want that racing.
    5402            try {
    5403                   //让仪器调用Application的onCreate()方法
                mInstrumentation.callApplicationOnCreate(app);
    5404            } catch (Exception e) {
    5405                if (!mInstrumentation.onException(app, e)) {
    5406                    throw new RuntimeException(
    5407                        "Unable to create application " + app.getClass().getName()
    5408                        + ": " + e.toString(), e);
    5409                }
    5410            }
    5411        } 
    5414    }
    
    • 根据loadedApk 调用 ContextImpl.createAppContext 创建了ContextImpl 对象,资源文件的读取操作都依赖于该ContextImpl 对象。
     final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    
    • 根据ContextImpl 的classLoader,加载Instrumentation 仪表盘类,利用返回实例化一个Instrumentation对象。
    final ApplicationInfo instrApp = new ApplicationInfo();
    5331            ii.copyTo(instrApp);
    5332            instrApp.initForUser(UserHandle.myUserId());
    5333            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
    5334                    appContext.getClassLoader(), false, true, false);
    5335            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
    5336
    5337            try {
    5338                final ClassLoader cl = instrContext.getClassLoader();
    5339                mInstrumentation = (Instrumentation)
    5340                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    5341            } catch (Exception e) {
    5342                throw new RuntimeException(
    5343                    "Unable to instantiate instrumentation "
    5344                    + data.instrumentationName + ": " + e.toString(), e);
    5345            }
    5346
    5347            final ComponentName component = new ComponentName(ii.packageName, ii.name);
    5348            mInstrumentation.init(this, instrContext, appContext, component,
    5349                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    

    Android instrumentation是Android系统里面的一套控制方法或者”钩子“。这些钩子可以在正常的生命周期(正常是由操作系统控制的)之外控制Android控件的运行。其实指的就是Instrumentation类提供的各种流程控制方法.
    然后我们继续发现callApplicationOnCreate要一个app参数,

    这个app是从哪里来的?继续像上看代码发现app产自这么一个方法makeApplication()

    public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
    if (mApplication != null) {
                return mApplication;
            }
    
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
    
            Application app = null;
    
            String appClass = mApplicationInfo.className;
            if (forceDefaultAppClass || (appClass == null)) {
                appClass = "android.app.Application";
            }
    
            try {
                java.lang.ClassLoader cl = getClassLoader();
                if (!mPackageName.equals("android")) {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                            "initializeJavaContextClassLoader");
                    initializeJavaContextClassLoader();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                }
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
    
    }
    

    发现是由一个叫LoadedApk的类去执行的,这个类是维护这本地已经加载的apk。如果有这个app就直接返回,没有就用反射创建一个,创建过程又交给了仪表盘mInstrumentation。

    static public Application newApplication(Class<?> clazz, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = (Application)clazz.newInstance();
            app.attach(context);
            return app;
        }
    

    简单的利用反射创建了application类,并调用了Application的attach()方法。

    Application类中attach()方法 会触发 attachBaseContext(context);的调用

      /**
    186     * @hide
    187     */
    188    /* package */ final void attach(Context context) {
    189        attachBaseContext(context);
    190        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    191    }
    192
    

    这就是我们经常见到的attachBaseContext()

    public class ContextWrapper extends Context
     protected void attachBaseContext(Context base) {
    66        if (mBase != null) {
    67            throw new IllegalStateException("Base context already set");
    68        }
    69        mBase = base;
    70    }
    }
    71
    

    至此Application的attachBaseContext()方法已经别正确调用。

    我们接着看H Handler中 handleBindApplication中的
    mInstrumentation.callApplicationOnCreate(app);方法

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

    直接调用了 Application的onCreate()方法

    二、知识点小结

    1、 Applicatio的启动过程

    从ActivityThread 的main()方法,

    ->到LoadedApk调用makeApplication()创建Application对象(实际上是Instrumentation创建的)

    ->再到Application类调用attach(),

    ->再到attachBaseContext()回调,

    ->最后调用Application类的onCreate()方法。

    一个应用程序Application就被启动起来了。

    2、ActivityThread中主要的成员和信息

    ActivityThread 是android程序的主入口。它内部包含了几个主要的内部类

    • final Looper mLooper = Looper.myLooper(); 主线程Looper
    • final H mH = new H(); 主线程消息循环的Handler,负责处理所有的消息事件。
    • final ApplicationThread mAppThread = new ApplicationThread(); ApplicationThread 类实现了以schedule***开头的操作Activity生命周期的回调函数。而这些回调函数中 大多会以 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);的形式 传递到H handler中来处理。

    三、参考文章:

    https://www.jianshu.com/p/673bd5cd6f9b

    相关文章

      网友评论

          本文标题:第一篇:Application启动流程分析

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