android 中主要對activity管理的幾個相關類。
ActivityRecord:通常的的 我們用的activity都是以繼承activity的形式出現,但是在系統中,每個 activity都是以activity record的形式出現,這個類包涵了 activity的各種資訊。 ActivityThread:負責管理并執行主線成中的各種請求。 ActivityManagerService:通過 ActivityManagerNative 類中的代理類 來實作 具體業務的管理者。 ActivityStack: activity的管理及各種狀态,一般的activity棧就是說的這個類,同時 還負責一些具體的類的操作 ActivityManagerService 通過調用 ActivityStack 來實習具體的操作,比如activity的開啟,關閉,等。 Trace:這個類 主要用來做資料分析,在代碼中 ActivityThread 在執行一些人物請求的時候,會調用 Trace中的一些方法來寫入和分析資料。 Instrumentation:application instrumentation 的 base. 這個類在應用執行個體化前開啟。他主要用來監聽所有系統用應用間的互動。 Instrumentation 通過 instrumentation 标簽來進行描述。
通過 onBackPressed 來看一下執行
public void onBackPressed() {
//2.0 < version < 3.0 沒有這個判斷 預設直接finis
if (!mFragments.popBackStackImmediate()) {
finish() ;
}
}
public void finish() {
if (mParent == null) {
int resultCode ;
Intent resultData ;
synchronized ( this) {
resultCode = mResultCode ;
resultData = mResultData ;
}
if ( false) Log.v(TAG , "Finishing self: token=" + mToken) ;
try {
if (resultData != null) {
resultData.setAllowFds( false) ;
}
//同樣最終調用的是 ActivityManagerService 中的 finishActivity 方法
//和startActivity一樣 還是先由 ActivityManagerNativen内部實作的一個代理類
//來實作 遠端服務 ActivityManagerService來實作
if (ActivityManagerNative.getDefault()
.finishActivity(mToken , resultCode , resultData)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild( this) ;
}
}
public final boolean finishActivity(IBinder token , int resultCode , Intent resultData) {
// Refuse possible leaked file descriptors
if (resultData != null && resultData.hasFileDescriptors() == true) {
throw new IllegalArgumentException( "File descriptors passed in Intent") ;
}
synchronized( this) {
if (mController != null) {
// Find the first activity that is not finishing.
//找到棧頂下一個 可以恢複的Activity
ActivityRecord next = mMainStack.topRunningActivityLocked(token , 0) ;
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
//判斷這個是否可以能恢複
resumeOK = mController.activityResuming(next.packageName) ;
} catch (RemoteException e) {
mController = null;
}
if (!resumeOK) {
return false;
}
}
}
final long origId = Binder.clearCallingIdentity() ;
//最終的執行者 是 ActivityStack 這個才是具體操作的執行者
//ActivityManagerService 将具體的任務 分給 ActivityStack去執行
boolean res = mMainStack.requestFinishActivityLocked(token , resultCode ,
resultData , "app-request") ;
Binder.restoreCallingIdentity(origId) ;
return res ;
}
}
final boolean requestFinishActivityLocked(IBinder token , int resultCode ,
Intent resultData , String reason) {
int index = indexOfTokenLocked(token) ; //判斷activity是否存在 存在就去那索引
if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(
TAG , "Finishing activity @" + index + ": token=" + token
+ ", result=" + resultCode + ", data=" + resultData
+ ", reason=" + reason) ;
if (index < 0) {
return false;
}
//拿到相對應的ActivityRecord
ActivityRecord r = mHistory.get(index) ;
finishActivityLocked(r , index , resultCode , resultData , reason) ;
return true;
}
final boolean finishActivityLocked(ActivityRecord r , int index ,
int resultCode , Intent resultData , String reason , boolean immediate) {
if (r.finishing) {
Slog.w(TAG , "Duplicate finish request for " + r) ;
return false;
}
r.makeFinishing() ;
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY ,
System.identityHashCode(r) ,
r.task.taskId , r.shortComponentName , reason) ;
if (index < (mHistory.size()- 1)) {
ActivityRecord next = mHistory.get(index+ 1) ;
if (next.task == r.task) {
if (r.frontOfTask) {
// The next activity is now the front of the task.
next.frontOfTask = true;
}
if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
// If the caller asked that this activity (and all above it)
// be cleared when the task is reset, don't lose that information,
// but propagate it up to the next activity.
next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) ;
}
}
}
//暫停這個類的一些操作,應該是這樣的 這個方法沒有細看
r.pauseKeyDispatchingLocked() ;
if (mMainStack) {
if (mService.mFocusedActivity == r) {
mService.setFocusedActivityLocked(topRunningActivityLocked( null)) ;
}
}
finishActivityResultsLocked(r , resultCode , resultData) ;
if (mService.mPendingThumbnails.size() > 0) {
// There are clients waiting to receive thumbnails so, in case
// this is an activity that someone is waiting for, add it
// to the pending list so we can correctly update the clients.
mService.mCancelledThumbnails.add(r) ;
}
//這裡傳入的是false 先不看這個判斷裡面的方法
if (immediate) { //這裡關閉activity
return finishCurrentActivityLocked(r , index ,
FINISH_IMMEDIATELY) == null;
} else if (mResumedActivity == r) {
boolean endTask = index <= 0
|| (mHistory.get(index- 1)).task != r.task ;
if (DEBUG_TRANSITION) Slog.v(TAG ,
"Prepare close transition: finishing " + r) ; //這裡應該是執行關閉動畫
mService.mWindowManager.prepareAppTransition(endTask
? WindowManagerPolicy.TRANSIT_TASK_CLOSE
: WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE , false) ;
// Tell window manager to prepare for this one to be removed.
mService.mWindowManager.setAppVisibility(r.appToken , false) ;
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG , "Finish needs to pause: " + r) ;
if (DEBUG_USER_LEAVING) Slog.v(TAG , "finish() => pause with userLeaving=false") ;
startPausingLocked( false, false) ;
}
} else if (r.state != ActivityState.PAUSING) {
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
if (DEBUG_PAUSE) Slog.v(TAG , "Finish not pausing: " + r) ;
//這裡 和 是不是和 true 執行的方法一樣
return finishCurrentActivityLocked(r , index ,
FINISH_AFTER_PAUSE) == null;
} else {
if (DEBUG_PAUSE) Slog.v(TAG , "Finish waiting for pause of: " + r) ;
}
return false;
}
private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r ,
int index , int mode) {
// First things first: if this activity is currently visible,
// and the resumed activity is not yet visible, then hold off on
// finishing until the resumed one becomes visible.
//如果這個将要顯示的activity沒有顯示,就等待他顯示之後執行關閉操作
if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
if (!mStoppingActivities.contains(r)) {
mStoppingActivities.add(r) ;
if (mStoppingActivities.size() > 3) {
// If we already have a few activities waiting to stop,
// then give up on things going idle and start clearing
// them out.
scheduleIdleLocked() ;
} else {
checkReadyForSleepLocked() ;
}
}
if (DEBUG_STATES) Slog.v(TAG , "Moving to STOPPING: " + r
+ " (finish requested)") ;
r.state = ActivityState.STOPPING ;
mService.updateOomAdjLocked() ;
return r ;
}
// make sure the record is cleaned out of other places.
//将存儲的要finish的activiy的資訊移除掉
mStoppingActivities.remove(r) ;
mGoingToSleepActivities.remove(r) ;
mWaitingVisibleActivities.remove(r) ;
if (mResumedActivity == r) {
mResumedActivity = null;
}
final ActivityState prevState = r.state ;
if (DEBUG_STATES) Slog.v(TAG , "Moving to FINISHING: " + r) ;
r.state = ActivityState.FINISHING ;
if (mode == FINISH_IMMEDIATELY
|| prevState == ActivityState.STOPPED
|| prevState == ActivityState.INITIALIZING) {
// If this activity is already stopped, we can just finish
// it right now.
boolean activityRemoved = destroyActivityLocked(r , true, true, "finish-imm") ;
if (activityRemoved) {
resumeTopActivityLocked( null) ;
}
return activityRemoved ? null : r ;
} else {
// Need to go through the full pause cycle to get this
// activity into the stopped state and then finish it.
if (localLOGV) Slog.v(TAG , "Enqueueing pending finish: " + r) ;
mFinishingActivities.add(r) ;
//将resume的activity放到頂部
resumeTopActivityLocked( null) ;
}
return r ;
}
在看 ActivityThread這個類 //這個變量是不是看起來非常眼熟 哈哈
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>() ;
AppBindData mBoundApplication ;
Profiler mProfiler ;
Configuration mConfiguration ;
Configuration mCompatConfiguration ;
Configuration mResConfiguration ;
CompatibilityInfo mResCompatibilityInfo ;
Application mInitialApplication ;
final ArrayList<Application> mAllApplications
= new ArrayList<Application>() ;
// set of instantiated backup agents, keyed by package name
final HashMap<String , BackupAgent> mBackupAgents = new HashMap<String , BackupAgent>() ;
static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>() ;
Instrumentation mInstrumentation ;
String mInstrumentationAppDir = null;
String mInstrumentationAppLibraryDir = null;
String mInstrumentationAppPackage = null;
String mInstrumentedAppDir = null;
String mInstrumentedAppLibraryDir = null;
boolean mSystemThread = false;
boolean mJitEnabled = false;
//這個内部類的方法是不是看起來更加的熟悉
private class ApplicationThread extends ApplicationThreadNative {
private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s" ;
private static final String ONE_COUNT_COLUMN = "%21s %8d" ;
private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d" ;
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s" ;
// Formatting for checkin service - update version if row format changes
private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1 ;
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) ;
}
public final void scheduleStopActivity(IBinder token , boolean showWindow ,
int configChanges) {
queueOrSendMessage(
showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE ,
token , 0 , configChanges) ;
}
public final void scheduleWindowVisibility(IBinder token , boolean showWindow) {
queueOrSendMessage(
showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW ,
token) ;
}
public final void scheduleSleeping(IBinder token , boolean sleeping) {
queueOrSendMessage(H.SLEEPING , token , sleeping ? 1 : 0) ;
}
public final void scheduleResumeActivity(IBinder token , boolean isForward) {
queueOrSendMessage(H.RESUME_ACTIVITY , token , isForward ? 1 : 0) ;
}
public final void scheduleSendResult(IBinder token , List<ResultInfo> results) {
ResultData res = new ResultData() ;
res.token = token ;
res.results = results ;
queueOrSendMessage(H.SEND_RESULT , res) ;
}
private void queueOrSendMessage( int what , Object obj , int arg1 , int arg2) {
synchronized ( this) {
if (DEBUG_MESSAGES) Slog.v(
TAG , "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj) ;
Message msg = Message.obtain() ;
msg.what = what ;
msg.obj = obj ;
msg.arg1 = arg1 ;
msg.arg2 = arg2 ;
mH.sendMessage(msg) ;
}
}
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100 ;
public static final int PAUSE_ACTIVITY = 101 ;
public static final int PAUSE_ACTIVITY_FINISHING= 102 ;
public static final int STOP_ACTIVITY_SHOW = 103 ;
public static final int STOP_ACTIVITY_HIDE = 104 ;
public static final int SHOW_WINDOW = 105 ;
public static final int HIDE_WINDOW = 106 ;
public static final int RESUME_ACTIVITY = 107 ;
public static final int SEND_RESULT = 108 ;
public static final int DESTROY_ACTIVITY = 109 ;
public static final int BIND_APPLICATION = 110 ;
public static final int EXIT_APPLICATION = 111 ;
public static final int NEW_INTENT = 112 ;
public static final int RECEIVER = 113 ;
public static final int CREATE_SERVICE = 114 ;
public static final int SERVICE_ARGS = 115 ;
public static final int STOP_SERVICE = 116 ;
public static final int REQUEST_THUMBNAIL = 117 ;
public static final int CONFIGURATION_CHANGED = 118 ;
public static final int CLEAN_UP_CONTEXT = 119 ;
public static final int GC_WHEN_IDLE = 120 ;
public static final int BIND_SERVICE = 121 ;
public static final int UNBIND_SERVICE = 122 ;
public static final int DUMP_SERVICE = 123 ;
public static final int LOW_MEMORY = 124 ;
public static final int ACTIVITY_CONFIGURATION_CHANGED = 125 ;
public static final int RELAUNCH_ACTIVITY = 126 ;
public static final int PROFILER_CONTROL = 127 ;
public static final int CREATE_BACKUP_AGENT = 128 ;
public static final int DESTROY_BACKUP_AGENT = 129 ;
public static final int SUICIDE = 130 ;
public static final int REMOVE_PROVIDER = 131 ;
public static final int ENABLE_JIT = 132 ;
public static final int DISPATCH_PACKAGE_BROADCAST = 133 ;
public static final int SCHEDULE_CRASH = 134 ;
public static final int DUMP_HEAP = 135 ;
public static final int DUMP_ACTIVITY = 136 ;
public static final int SLEEPING = 137 ;
public static final int SET_CORE_SETTINGS = 138 ;
public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139 ;
public static final int TRIM_MEMORY = 140 ;
public static final int DUMP_PROVIDER = 141 ;
public static final int UNSTABLE_PROVIDER_DIED = 142 ;
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;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER , "activityRestart") ;
ActivityClientRecord r = (ActivityClientRecord)msg.obj ;
handleRelaunchActivity(r) ;
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER) ;
} break;
case PAUSE_ACTIVITY:
// Trace 是不是出現了
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER , "activityPause") ;
handlePauseActivity((IBinder)msg.obj , false, msg.arg1 != 0 , msg.arg2) ;
maybeSnapshot() ;
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER) ;
break;
private void handlePauseActivity(IBinder token , boolean finished ,
boolean userLeaving , int configChanges) {
ActivityClientRecord r = mActivities.get(token) ;
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r) ;
}
r.activity.mConfigChangeFlags |= configChanges ;
performPauseActivity(token , finished , r.isPreHoneycomb()) ;
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish() ;
}
// Tell the activity manager we have paused.
try {
//最終結果 又走向了 ActivityManagerService
ActivityManagerNative.getDefault().activityPaused(token) ;
} catch (RemoteException ex) {
}
}
}
隻是簡單粗略的來一個分析, 有時間 這幾個類 還是要詳細的看一下 其中還包含了好幾個設計模式。