美文网首页
第一篇: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