http://blog.csdn.net/myarrow/article/details/14224273
1. 基本概念
1.1 Instrumentation是什么?
顧名思義,儀器儀表,用於在應用程序中進行“測量”和“管理”工作。一個應用程序中只有一個Instrumentation實例對象,且每個Activity都有此對象的引用。Instrumentation將在任何應用程序運行前初始化,可以通過它監測系統與應用程序之間的所有交互,即類似於在系統與應用程序之間安裝了個“竊聽.器”。
當ActivityThread 創建(callActivityOnCreate)、暫停、恢復某個Activity時,通過調用此對象的方法來實現,如:
1) 創建: callActivityOnCreate
2) 暫停: callActivityOnPause
3) 恢復: callActivityOnResume
Instrumentation和ActivityThread的關系,類似於老板與經理的關系,老板負責對外交流(如與Activity Manager Service<AMS>),Instrumentation負責管理並完成老板交待的任務。
它通過以下兩個成員變量來對當前應用進程中的Activity進行管理:
- private List<ActivityWaiter> mWaitingActivities;
- private List<ActivityMonitor> mActivityMonitors;
其功能函數下表所示:
功能 | 函數 |
增加刪除Monitor | addMonitor(ActivityMonitor monitor) removeMonitor(ActivityMonitor monitor) |
Application與Activity生命周期控制 | newApplication(Class<?> clazz, Context context) newActivity(ClassLoader cl, String className,Intent intent) callActivityOnCreate(Activity activity, Bundle icicle) callActivityOnDestroy(Activity activity) callActivityOnStart(Activity activity) callActivityOnRestart(Activity activity) callActivityOnResume(Activity activity) callActivityOnStop(Activity activity) callActivityOnPause(Activity activity) |
Instrumentation生命周期控制 | onCreate(Bundle arguments) start() onStart() finish(int resultCode, Bundle results) onDestroy() |
發送用戶操控信息到當前窗口 | sendCharacterSync(int keyCode) sendPointerSync(MotionEvent event) sendTrackballEventSync(MotionEvent event) sendTrackballEventSync(MotionEvent event) |
同步操作 | startActivitySync(Intent intent) //它調用Context.startActivity runOnMainSync(Runnable runner) waitForIdle() |
2. Android應用程序啟動過程(MainActivity)
即MainActivity的啟動過程,在此過程中,將創建一個新的進程來執行此MainActivity。
Android應用程序從Launcher啟動流程如下所示:
- /*****************************************************************
- * Launcher通過Binder告訴ActivityManagerService,
- * 它將要啟動一個新的Activity;
- ****************************************************************/
- Launcher.startActivitySafely->
- Launcher.startActivity->
- //要求在新的Task中啟動此Activity
- //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- Activity.startActivity->
- Activity.startActivityForResult->
- Instrumentation.execStartActivity->
- // ActivityManagerNative.getDefault()返回AMS Proxy接口
- ActivityManagerNative.getDefault().startActivity->
- ActivityManagerProxy.startActivity->
- ActivityManagerService.startActivity-> (AMS)
- ActivityManagerService.startActivityAsUser->
- ActivityStack.startActivityMayWait->
- ActivityStack.resolveActivity(獲取ActivityInfo)
- //aInfo.name為main Activity,如:com.my.test.MainActivity
- //aInfo.applicationInfo.packageName為包名,如com.my.test
- ActivityStack.startActivityLocked->
- //ProcessRecord callerApp; 調用者即Launcher信息
- //ActivityRecord sourceRecord; Launcher Activity相關信息
- //ActivityRecord r=new ActivityRecord(...),將要創建的Activity相關信息
- ActivityStack.startActivityUncheckedLocked->
- //Activity啟動方式:ActivityInfo.LAUNCH_MULTIPLE/LAUNCH_SINGLE_INSTANCE/
- // ActivityInfo.LAUNCH_SINGLE_TASK/LAUNCH_SINGLE_TOP)
- // 創建一個新的task,即TaskRecord,並保存在ActivityRecord.task中
- //r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true)
- // 把新創建的Activity放在棧頂
- ActivityStack.startActivityLocked->
- ActivityStack.resumeTopActivityLocked->
- ActivityStack.startPausingLocked (使Launcher進入Paused狀態)->
- /*****************************************************************
- * AMS通過Binder通知Launcher進入Paused狀態
- ****************************************************************/
- ApplicationThreadProxy.schedulePauseActivity->
- //private class ApplicationThread extends ApplicationThreadNative
- ApplicationThread.schedulePauseActivity->
- ActivityThread.queueOrSendMessage->
- // 調用Activity.onUserLeaveHint
- // 調用Activity.onPause
- // 通知activity manager我進入了pause狀態
- ActivityThread.handlePauseActivity->
- /*****************************************************************
- * Launcher通過Binder告訴AMS,它已經進入Paused狀態
- ****************************************************************/
- ActivityManagerProxy.activityPaused->
- ActivityManagerService.activityPaused->
- ActivityStack.activityPaused->(把Activity狀態修改為PAUSED)
- ActivityStack.completePauseLocked->
- // 參數為代表Launcher這個Activity的ActivityRecord
- // 使用棧頂的Activity進入RESUME狀態
- ActivityStack.resumeTopActivityLokced->
- //topRunningActivityLocked將剛創建的放於棧頂的activity取回來
- // 即在ActivityStack.startActivityUncheckedLocked中創建的
- /*****************************************************************
- * AMS創建一個新的進程,用來啟動一個ActivityThread實例,
- * 即將要啟動的Activity就是在這個ActivityThread實例中運行
- ****************************************************************/
- ActivityStack.startSpecificActivityLocked->
- // 創建對應的ProcessRecord
- ActivityManagerService.startProcessLocked->
- // 啟動一個新的進程
- // 新的進程會導入android.app.ActivityThread類,並且執行它的main函數,
- // 即實例化ActivityThread, 每個應用有且僅有一個ActivityThread實例
- Process.start("android.app.ActivityThread",...)->
- // 通過zygote機制創建一個新的進程
- Process.startViaZygote->
- // 這個函數在進程中創建一個ActivityThread實例,然后調用
- // 它的attach函數,接着就進入消息循環
- ActivityThread.main->
- /*****************************************************************
- * ActivityThread通過Binder將一個ApplicationThread類的Binder對象
- * 傳遞給AMS,以便AMS通過此Binder對象來控制Activity整個生命周期
- ****************************************************************/
- ActivityThread.attach->
- IActivityManager.attachApplication(mAppThread)->
- ActivityManagerProxy.attachApplication->
- ActivityManagerService.attachApplication->
- // 把在ActivityManagerService.startProcessLocked中創建的ProcessRecord取出來
- ActivityManagerService.attachApplicationLocked->
- /*****************************************************************
- * AMS通過Binder通知ActivityThread一切准備OK,它可以真正啟動新的Activity了
- ****************************************************************/
- // 真正啟動Activity
- ActivityStack.realStartActivityLocked->
- ApplicationThreadProxy.scheduleLaunchActivity->
- ApplicationThread.scheduleLaunchActivity->
- ActivityThread.handleLaunchActivity->
- // 加載新的Activity類,並執行它的onCreate
- ActivityThread.performLaunchActivity
- /*1) Instrumentation.newActivity: 加載新類,即創建Activity對象;
- 2) ActivityClientRecord.packageInfo.makeApplication:創建Application對象;
- <LoadedApk.makeApplication>
- 3) Activity.attach(Context context, ActivityThread aThread,
- Instrumentation instr, IBinder token, int ident,
- Application application, Intent intent, ActivityInfo info,
- CharSequence title, Activity parent, String id,
- NonConfigurationInstances lastNonConfigurationInstances,
- Configuration config):把Application attach到Activity, 即把Activtiy
- 相關信息設置到新創建的Activity中
- 4) Instrumentation.callActivityOnCreate:調用onCreate;*/
- // 使用Activity進入RESUMED狀態,並調用onResume
- ActivityThread.handleResumeActivity
3. ActivityManagerService
3.1 類中關鍵信息
- public final class ActivityManagerService extends ActivityManagerNative
- implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
- ...
- // Maximum number of recent tasks that we can remember.
- static final int MAX_RECENT_TASKS = 20;
- public ActivityStack mMainStack; // 管理Activity堆棧
- // Whether we should show our dialogs (ANR, crash, etc) or just perform their
- // default actuion automatically. Important for devices without direct input
- // devices.
- private boolean mShowDialogs = true;
- /**
- * Description of a request to start a new activity, which has been held
- * due to app switches being disabled.
- */
- static class PendingActivityLaunch {
- ActivityRecord r;
- ActivityRecord sourceRecord;
- int startFlags;
- }
- /**
- * Activity we have told the window manager to have key focus.
- */
- ActivityRecord mFocusedActivity = null;
- /**
- * List of intents that were used to start the most recent tasks.
- */
- final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
- /**
- * Process management.
- */
- final ProcessList mProcessList = new ProcessList();
- /**
- * All of the applications we currently have running organized by name.
- * The keys are strings of the application package name (as
- * returned by the package manager), and the keys are ApplicationRecord
- * objects.
- */
- final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
- /**
- * The currently running isolated processes.
- */
- final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
- ...
- public static final Context main(int factoryTest) { //main入口函數
- AThread thr = new AThread();
- thr.start();
- synchronized (thr) {
- while (thr.mService == null) {
- try {
- thr.wait();
- } catch (InterruptedException e) {
- }
- }
- }
- ActivityManagerService m = thr.mService;
- mSelf = m;
- ActivityThread at = ActivityThread.systemMain();
- mSystemThread = at;
- Context context = at.getSystemContext();
- context.setTheme(android.R.style.Theme_Holo);
- m.mContext = context;
- m.mFactoryTest = factoryTest;
- m.mMainStack = new ActivityStack(m, context, true); // 創建ActivityStack
- m.mBatteryStatsService.publish(context);
- m.mUsageStatsService.publish(context);
- synchronized (thr) {
- thr.mReady = true;
- thr.notifyAll();
- }
- m.startRunning(null, null, null, null);
- return context;
- }
- }
3.2 家族圖譜
4. ActivityStack-真正做事的家伙
ActivityManagerService使用它來管理系統中所有的Activities的狀態,Activities使用stack的方式進行管理。它是真正負責做事的家伙,很勤快的,但外界無人知道!
4.1 類中關鍵信息
- /**
- * State and management of a single stack of activities.
- */
- final class ActivityStack {
- final ActivityManagerService mService;
- final boolean mMainStack;
- final Context mContext;
- enum ActivityState {
- INITIALIZING,
- RESUMED,
- PAUSING,
- PAUSED,
- STOPPING,
- STOPPED,
- FINISHING,
- DESTROYING,
- DESTROYED
- }
- /**
- * The back history of all previous (and possibly still
- * running) activities. It contains HistoryRecord objects.
- */
- final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>();
- /**
- * Used for validating app tokens with window manager.
- */
- final ArrayList<IBinder> mValidateAppTokens = new ArrayList<IBinder>();
- /**
- * List of running activities, sorted by recent usage.
- * The first entry in the list is the least recently used.
- * It contains HistoryRecord objects.
- */
- final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>();
- /**
- * List of activities that are waiting for a new activity
- * to become visible before completing whatever operation they are
- * supposed to do.
- */
- final ArrayList<ActivityRecord> mWaitingVisibleActivities
- = new ArrayList<ActivityRecord>();
- /**
- * List of activities that are ready to be stopped, but waiting
- * for the next activity to settle down before doing so. It contains
- * HistoryRecord objects.
- */
- final ArrayList<ActivityRecord> mStoppingActivities
- = new ArrayList<ActivityRecord>();
- /**
- * List of activities that are in the process of going to sleep.
- */
- final ArrayList<ActivityRecord> mGoingToSleepActivities
- = new ArrayList<ActivityRecord>();
- /**
- * When we are in the process of pausing an activity, before starting the
- * next one, this variable holds the activity that is currently being paused.
- */
- ActivityRecord mPausingActivity = null;
- /**
- * This is the last activity that we put into the paused state. This is
- * used to determine if we need to do an activity transition while sleeping,
- * when we normally hold the top activity paused.
- */
- ActivityRecord mLastPausedActivity = null;
- /**
- * Current activity that is resumed, or null if there is none.
- */
- ActivityRecord mResumedActivity = null;
- /**
- * This is the last activity that has been started. It is only used to
- * identify when multiple activities are started at once so that the user
- * can be warned they may not be in the activity they think they are.
- */
- ActivityRecord mLastStartedActivity = null;
- /**
- * Set to indicate whether to issue an onUserLeaving callback when a
- * newly launched activity is being brought in front of us.
- */
- boolean mUserLeaving = false;
- ActivityStack(ActivityManagerService service, Context context, boolean mainStack) {
- mService = service;
- mContext = context;
- mMainStack = mainStack;
- ...
- }
- ...
- }
4.2 家族圖譜
5. ProcessRecord
記錄了一個進程的相關信息。
5.1 類中關鍵信息
- /**
- * Full information about a particular process that
- * is currently running.
- */
- class ProcessRecord {
- final ApplicationInfo info; // all about the first app in the process
- final boolean isolated; // true if this is a special isolated process
- final int uid; // uid of process; may be different from 'info' if isolated
- final int userId; // user of process.
- final String processName; // name of the process
- IApplicationThread thread; // the actual proc... may be null only if
- // 'persistent' is true (in which case we
- // are in the process of launching the app)
- // 是ApplicationThread對象的遠程接口,
- // 通過此接口通知Activity進入對應的狀態
- int pid; // The process of this application; 0 if none
- ApplicationInfo instrumentationInfo; // the application being instrumented
- BroadcastRecord curReceiver;// receiver currently running in the app
- // contains HistoryRecord objects
- final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
- // all ServiceRecord running in this process
- final HashSet<ServiceRecord> services = new HashSet<ServiceRecord>();
- // services that are currently executing code (need to remain foreground).
- final HashSet<ServiceRecord> executingServices
- = new HashSet<ServiceRecord>();
- // All ConnectionRecord this process holds
- final HashSet<ConnectionRecord> connections
- = new HashSet<ConnectionRecord>();
- // all IIntentReceivers that are registered from this process.
- final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
- // class (String) -> ContentProviderRecord
- final HashMap<String, ContentProviderRecord> pubProviders
- = new HashMap<String, ContentProviderRecord>();
- // All ContentProviderRecord process is using
- final ArrayList<ContentProviderConnection> conProviders
- = new ArrayList<ContentProviderConnection>();
- boolean persistent; // always keep this application running?
- boolean crashing; // are we in the process of crashing?
- Dialog crashDialog; // dialog being displayed due to crash.
- boolean notResponding; // does the app have a not responding dialog?
- Dialog anrDialog; // dialog being displayed due to app not resp.
- boolean removed; // has app package been removed from device?
- boolean debugging; // was app launched for debugging?
- boolean waitedForDebugger; // has process show wait for debugger dialog?
- Dialog waitDialog; // current wait for debugger dialog
- ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
- ApplicationInfo _info, String _processName, int _uid) {
- batteryStats = _batteryStats;
- info = _info;
- isolated = _info.uid != _uid;
- uid = _uid;
- userId = UserHandle.getUserId(_uid);
- processName = _processName;
- pkgList.add(_info.packageName);
- thread = _thread;
- maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
- hiddenAdj = clientHiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
- curRawAdj = setRawAdj = -100;
- curAdj = setAdj = -100;
- persistent = false;
- removed = false;
- }
- ...
- }
5. 2 家族圖譜
6. IApplicationThread接口AMS->Application
IApplicationThread為AMS作為客戶端訪問Application服務器端的Binder接口。當創建Application時,將把此Binder對象傳遞給AMS,然后AMS把它保存在mProcessNames.ProcessRecord.thread中。當需要通知Application工作時,則調用IApplicationThread中對應的接口函數。
其相互關系如下圖所示: