ActivityThread
1. ActivityThread 功能 它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client、ActivityThread.ApplicationThread为Server)负责调度和执行activities、broadcasts和其它操作。 在Android系统中,在默认情况下,一个应用程序内的各个组件(如Activity、BroadcastReceiver、Service)都会在同一个进程(Process)里执行,且由此进程的【主线程】负责执行。 在Android系统中,如果有特别指定(通过android:process),也可以让特定组件在不同的进程中运行。无论组件在哪一个进程中运行,默认情况下,他们都由此进程的【主线程】负责执行。 【主线程】既要处理Activity组件的UI事件,又要处理Service后台服务工作,通常会忙不过来。为了解决此问题,主线程可以创建多个子线程来处理后台服务工作,而本身专心处理UI画面的事件。 【主线程】的主要责任: •快速处理UI事件。而且只有它才处理UI事件, 其它线程还不能存取UI画面上的对象(如TextView等),此时, 主线程就叫做UI线程。基本上,Android希望UI线程能根据用户的要求做出快速响应,如果UI线程花太多时间处理后台的工作,当UI事件发生时,让用户等待时间超过5秒而未处理,Android系统就会给用户显示ANR提示信息。 只有UI线程才能执行View派生类的onDraw()函数。 • 快速处理Broadcast消息。【主线程】除了处理UI事件之外,还要处理Broadcast消息。所以在BroadcastReceiver的onReceive()函数中,不宜占用太长的时间,否则导致【主线程】无法处理其它的Broadcast消息或UI事件。如果占用时间超过10秒, Android系统就会给用户显示ANR提示信息。 注意事项: •尽量避免让【主线程】执行耗时的操作,让它能快速处理UI事件和Broadcast消息。 •BroadcastReceiver的子类都是无状态的,即每次启动时,才会创建其对象,然后调用它的onReceive()函数,当执行完onReceive()函数时,就立即删除此对象。由于每次调用其函数时,会重新创建一个新的对象,所以对象里的属性值,是无法让各函数所共享。 1.1 Thread与SurfaceView View组件由UI线程(主线程)所执行。如果需要迅速更新UI画面或UI画图需要较长时间,则需要使用SurfaceView。它可由后台线程(background thread)来执行,而View只能由UI(主)线程执行。SurfaceView内有高效的rendering机制,可以让后台线程快速刷新Surface的内容。 View ---> UI(主)线程 SurfaceView ---> 后台线程 2. Android应用程序主线程stack 在一个只有Activity派生类的应用程序中,它包含如下线程:
main 线程 stack 如下: at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:118) at android.os.Looper.loop(Looper.java:118) at android.app.ActivityThread.main(ActivityThread.java:4424) // Java main入口函数 at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) JDWP线程stack如下: at org.apache.harmony.dalvik.ddmc.DdmVmInternal.getStackTraceById(Native Method) at android.ddm.DdmHandleThread.handleSTKL(DdmHandleThread.java:131) at android.ddm.DdmHandleThread.handleChunk(DdmHandleThread.java:77) at org.apache.harmony.dalvik.ddmc.DdmServer.dispatch(DdmServer.java:171) at dalvik.system.NativeStart.run(Native Method) 3. IApplicationThread 关系图
4. ActivityThread类 ActivityThread 类即代表 Application 主线程。 4.1 类中关键信息 public final class ActivityThread { static ContextImpl mSystemContext = null; static IPackageManager sPackageManager; // 创建ApplicationThread实例,以接收AMS指令并执行 final ApplicationThread mAppThread = new ApplicationThread(); final Looper mLooper = Looper.myLooper(); final H mH = new H(); final HashMap<IBinder, ActivityClientRecord> mActivities = new HashMap<IBinder, ActivityClientRecord>(); // List of new activities (via ActivityRecord.nextIdle) that should // be reported when next we idle. ActivityClientRecord mNewActivities = null; // Number of activities that are currently visible on-screen. int mNumVisibleActivities = 0; final HashMap<IBinder, Service> mServices = new HashMap<IBinder, Service>(); Application mInitialApplication; final ArrayList<Application> mAllApplications = new ArrayList<Application>(); static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>(); Instrumentation mInstrumentation; static Handler sMainThreadHandler; // set once in main() static final class ActivityClientRecord { IBinder token; int ident; Intent intent; Bundle state; Activity activity; Window window; Activity parent; String embeddedID; Activity.NonConfigurationInstances lastNonConfigurationInstances; boolean paused; boolean stopped; boolean hideForNow; Configuration newConfig; Configuration createdConfig; ActivityClientRecord nextIdle; String profileFile; ParcelFileDescriptor profileFd; boolean autoStopProfiler; ActivityInfo activityInfo; CompatibilityInfo compatInfo; LoadedApk packageInfo; //包信息,通过调用ActivityThread.getPapckageInfo而获得 List<ResultInfo> pendingResults; List<Intent> pendingIntents; boolean startsNotResumed; boolean isForward; int pendingConfigChanges; boolean onlyLocalRequest; View mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager; ... } private class ApplicationThread extends ApplicationThreadNative { private void updatePendingConfiguration(Configuration config) { synchronized (mPackages) { if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(config)) { mPendingConfiguration = config; } } } public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges) { queueOrSendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? 1 : 0), configChanges); } // we use token to identify this activity without having to send the // activity itself back to the activity manager. (matters more with ipc) public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, Bundle state, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { ActivityClientRecord r = new ActivityClientRecord(); r.token = token; r.ident = ident; r.intent = intent; r.activityInfo = info; r.compatInfo = compatInfo; r.state = state; r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed; r.isForward = isForward; r.profileFile = profileName; r.profileFd = profileFd; r.autoStopProfiler = autoStopProfiler; updatePendingConfiguration(curConfig); queueOrSendMessage(H.LAUNCH_ACTIVITY, r); } ... } private class H extends Handler { public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; ... } if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); } ... } public static ActivityThread currentActivityThread() { return sThreadLocal.get(); } public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); // 创建ActivityThread实例 ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); } } 4.2 家族图谱