編輯:關於Android編程
//將待啟動的Activity放入棧頂 final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition, Bundle options) { TaskRecord rTask = r.task; final int taskId = rTask.taskId; if (taskForIdLocked(taskId) == null || newTask) { // 如果是新任務,則將任務插入到任務列表頂端 insertTaskAtTop(rTask);//將當前task置於頂部 mWindowManager.moveTaskToTop(taskId); } TaskRecord task = null; if (!newTask) { // If starting in an existing task, find where that is... boolean startIt = true; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { task = mTaskHistory.get(taskNdx); /// M: ALPS01315669, fix google KK bug, skip activity if it is finishing like JB @{ boolean findTask = false; for (int index = task.mActivities.size() - 1; index >=0; --index) { ActivityRecord p = task.mActivities.get(index); if (p.finishing) { continue; } if (p.task == r.task) { //如果不是在新的ActivityTask(也就是TaskRecord)中的話,就找出要運行在的TaskRecord對象 // Here it is! Now, if this is not yet visible to the // user, then just add it without starting; it will // get started when the user navigates back to it. if (!startIt) {//默認情況下此處不執行 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task, new RuntimeException("here").fillInStackTrace()); task.addActivityToTop(r); r.putInHistory(); /// M: Add for Activity Stack Parser @{ if (null != mStackListener){ mStackListener.dumpStack(mTaskHistory); } /// @} mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, r.info.configChanges); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } ActivityOptions.abort(options); return; } findTask = true; break; } else if (p.fullscreen) { startIt = false; } } if (findTask) { break; } /// @} }
if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) { mStackSupervisor.mUserLeaving = false;//當用戶按Home鍵等操作使程序進入後台時 就會根據mUserLeaving=true, //調用onUserLeaveHint(), //onUserLeaveHint //這個回調函數主要用來監聽按Home鍵退出到桌面的動作,發生在onPause之前。在啟動一個新的Activity時, //ActivityStackSupervisor裡會調用startActivityUncheckedLocked,在它裡面會給mUserLeaving賦值。 //mUserLeaving用於指示當前activity退到後台時函數onUserLeaving是否被調用。 //可見,只有當設置了FLAG_ACTIVITY_NO_USER_ACTION標志時mUserLeaving才會為false, //其他情況下mUserLeaving均為true,也就是onUserLeaveHint會被調用,注釋裡也說了onUserLeaveHint會在onPause之前被調用。 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() behind front, mUserLeaving=false"); } ///kf/201503/380568.html task = r.task;
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); // Find the first activity that is not finishing. ActivityRecord next = topRunningActivityLocked(null); // Remember how we'll process this pause/resume situation, and ensure // that the state is reset however we wind up proceeding. final boolean userLeaving = mStackSupervisor.mUserLeaving;//如果被置位說明這是被鬧鐘啟動的話為true, //處理FLAG_ACTIVITY_NO_USER_ACTION情況,如果該標志位為1,則表示並非是用戶主觀意願啟動的Activity // 具體情況如來電、鬧鐘事件等,此時mUserLeaving為false mStackSupervisor.mUserLeaving = false; if (next == null) {//啟動桌面 // There are no more activities! Let's just start up the // Launcher... ActivityOptions.abort(options); /// M: Power off alarm feature: /// If mAlarmBoot is TRUE, that means this is alarm boot-up /// We will skip to resume home activity until the Alarm activity is destroyed. @{ if (PowerOffAlarmUtility.isAlarmBoot()) { Slog.v(TAG, "Skip to resume home activity!!"); return false; } /// @} if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home"); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return mStackSupervisor.resumeHomeActivity(prev); } next.delayedResume = false; // If the top activity is the resumed one, nothing to do. //如果next即是當前需要啟動的Activity組件,並且其狀態為resumed,則不需要進行任何操作 //,表示當前Activity組件已經處於啟動和激活了 //mResumedActivity當前正在顯示的Activity if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) { // Make sure we have executed any pending transitions, since there // should be nothing left to do at this point. mWindowManager.executeAppTransition(); mNoAnimActivities.clear(); ActivityOptions.abort(options); if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return false; } final TaskRecord nextTask = next.task; final TaskRecord prevTask = prev != null ? prev.task : null; if (prevTask != null && prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) { //上一個prev Task 不為null 並且上一個 pre task 退出時候要啟動home,並且 pre Activity已經結束且pre Activity是起始Activity if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); if (prevTask == nextTask) {//但是這 要啟動的Task和pre task是同一個。 ArrayList activities = prevTask.mActivities; final int numActivities = activities.size(); for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { final ActivityRecord r = activities.get(activityNdx); // r is usually the same as next, but what if two activities were launched // before prev finished? if (!r.finishing) {//此時應該這樣理解 if (!r.finishing) 要找到要啟動activity,因為只有要啟動activity沒有finishing, //一個task 可以有幾個起始activity,由於當前要啟動的activity 與prev.frontOfTask 不同。所以我們要重新設置frontOfTask r.frontOfTask = true;//棧底作為入口 activity break; } } } else if (prevTask != topTask()) { // This task is going away but it was supposed to return to the home task. // Now the task above it has to return to the home task instead. final int taskNdx = mTaskHistory.indexOf(prevTask) + 1; mTaskHistory.get(taskNdx).mOnTopOfHome = true;//新任務代替返回home task } else { if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Launching home next"); return mStackSupervisor.resumeHomeActivity(prev);//啟動home } } else { /// M: Fix ALPS01260522 /// If there are some task (must contain pending finishing activity) with mOnTopOfHome above next activity, /// we should resume home activity @{ boolean needResumeHome = false; for (int taskIndex = mTaskHistory.size() - 1; taskIndex >= 0; taskIndex--) { TaskRecord task = mTaskHistory.get(taskIndex); if (next.task == task || task.mMovingToFront) {//在這種情況下。正在啟動的task就是當前task,此時不需要啟動home break; } else if (task.mOnTopOfHome) {//若當前mOnTopOfHome = true 表示返回的時候啟動home Slog.d(TAG, "Find previous pending finishing task with mOnTopOfHome: " + task); needResumeHome = true; break; } } if (needResumeHome) { Slog.d(TAG, "resumeTopActivityLocked: Launching home due to previous pending finishing task"); return mStackSupervisor.resumeHomeActivity(prev); }
if (mService.isSleepingOrShuttingDown()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
// 如果當前的next是要顯示的Activity,而且上次剛暫停的Activity正好也是next,並且系統正要進入關機或者睡眠狀態
//說明系統要睡眠。
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG, “resumeTopActivityLocked: Going to sleep and all paused”);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
// Make sure that the user who owns this activity is started. If not,
// we will just leave it as is because someone should be bringing
// another user's activities to the top of the stack.
if (mService.mStartedUsers.get(next.userId) == null) {//判斷當前要resume的Activity所屬的userID是否已經起來
Slog.w(TAG, "Skipping resume of top activity " + next
+ ": user " + next.userId + " is stopped");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mStackSupervisor.mStoppingActivities.remove(next);//next是要馬上啟動的。所以從mStoppingActivities 移除
mStackSupervisor.mGoingToSleepActivities.remove(next);//同理以上
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
//如果要resume一個Activity,那麼必然要清掉mStoppingActivities、mGoingToSleepActivities、mWaitingVisibleActivities列表中該Activity
next.updateOptionsLocked(options);
if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
// If we are currently pausing an activity, then don't do anything
// until that is done.
if (!mStackSupervisor.allPausedActivitiesComplete()) {//再暫停完pre Activity之前,我們什麼都不做
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG,
"resumeTopActivityLocked: Skip resume: some activity pausing.");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
//前面說了,在調用resumeTopActivityLocked()已經做好了Stack、Task等准備,但是還沒pause 前一個Stack中的resumed Activity
//,或者沒有pause掉本Stack中resumed activity。此時便進行觸發pause操作
//,然後返回,等待pause完成後調用completePauseLocked()–>resumeTopActivityLocked()再次嘗試resume,此時便可繼續往下執行。
//mStackSupervisor.mUserLeaving的值在過程5中被設置為true,此處取出來賦值給userLeaving
//,表明是用戶操作行為(按下返回鍵,HOME按鍵等);無論是true還是false,此處還是再復位一下
//,重新設置為false
if (mResumedActivity != null) {
pausing = true;
startPausingLocked(userLeaving, false);
if (DEBUG_STATES) Slog.d(TAG, “resumeTopActivityLocked: Pausing ” + mResumedActivity);
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
“resumeTopActivityLocked: Skip resume: need to start pausing”);
// At this point we want to put the upcoming activity’s process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.app != null && next.app.thread != null) {
// No reason to do full oom adj update here; we’ll let that
// happen whenever it needs to later.
mService.updateLruProcessLocked(next.app, true, null);
//調整進程調度優先級和OOM_Adj
//參考http://blog.csdn.net/yujun411522/article/details/46682687
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
if (mService.mSleeping && mLastNoHistoryActivity != null &&
!mLastNoHistoryActivity.finishing) {
if (DEBUG_STATES) Slog.d(TAG, "no-history finish of " + mLastNoHistoryActivity +
" on new resume");
requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
null, "no-history", false);//確認 在mLastNoHistoryActivity 列表的Activity都已經被結束
mLastNoHistoryActivity = null;
//例如現在棧情況為:A B C。C通過intent跳轉到D,這個intent添加FLAG_ACTIVITY_NO_HISTORY標志
//,則此時界面顯示D的內容,但是它並不會壓入棧中。如果按返回鍵,返回到C,棧的情況還是:A B C
//。如果此時D中又跳轉到E,棧的情況變為:A B C E,此時按返回鍵會回到C,因為D根本就沒有被壓入棧中。
}
if (prev != null && prev != next) {
if (!prev.waitingVisible && next != null && !next.nowVisible) {
prev.waitingVisible = true;
//prev 置位true表示等待 next顯示。nowVisible 表示 next要顯示
mStackSupervisor.mWaitingVisibleActivities.add(prev);
if (DEBUG_SWITCH) Slog.v(
TAG, "Resuming top, waiting visible to hide: " + prev);
} else {
// 如果當前Activity已經是可見,所以我們需要立即hide之間的Activity界面以便能夠盡快地顯示新Activity界面
if (prev.finishing) {
mWindowManager.setAppVisibility(prev.appToken, false);
if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
+ prev + ", waitingVisible="
+ (prev != null ? prev.waitingVisible : null)
+ ", nowVisible=" + next.nowVisible);
} else {
if (DEBUG_SWITCH) Slog.v(TAG, "Previous already visible but still waiting to hide: "
+ prev + ", waitingVisible="
+ (prev != null ? prev.waitingVisible : null)
+ ", nowVisible=" + next.nowVisible);
}
}
}
// Launching this app's activity, make sure the app is no longer
// considered stopped.
//啟動新Activity
try {
AppGlobals.getPackageManager().setPackageStoppedState(
next.packageName, false, next.userId); /* TODO: Verify if correct userid */
} catch (RemoteException e1) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ next.packageName + ": " + e);
}
//如果pre Activity已經被finish了,那麼直接隱藏pre Activity的窗口好了。如果沒有被finish呢
//?那就先不管,反正next Activity的窗口肯定會覆蓋pre Activity的窗口之上
//。從這個邏輯可以看出一個Activity只有在finish掉時窗口才設為不可見,pause狀態窗口是可見的
//,同時也可以知道Activity切換動畫是在resume next Activity時啟動的。
boolean anim = true;
if (prev != null) {
if (prev.finishing) {
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare close transition: prev=" + prev);
if (mNoAnimActivities.contains(prev)) {//不要錢過度動畫
anim = false;
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
//prepareAppTransition 詳細看雲筆記
} else {
mWindowManager.prepareAppTransition(prev.task == next.task
? AppTransition.TRANSIT_ACTIVITY_CLOSE
: AppTransition.TRANSIT_TASK_CLOSE, false);
//TRANSIT_ACTIVITY_CLOSE:關閉當前活動窗口,恢復同一個task中的上一個窗口
//TRANSIT_TASK_CLOSE:關閉當前活動窗口,回到上一個任務
}
mWindowManager.setAppWillBeHidden(prev.appToken);//pre v的Activity隱藏
mWindowManager.setAppVisibility(prev.appToken, false);
} else {
if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev);
if (mNoAnimActivities.contains(next)) {
anim = false;
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(prev.task == next.task
? AppTransition.TRANSIT_ACTIVITY_OPEN
: AppTransition.TRANSIT_TASK_OPEN, false);
}
}
if (false) {
mWindowManager.setAppWillBeHidden(prev.appToken);
mWindowManager.setAppVisibility(prev.appToken, false);
}
} else {
if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous");
if (mNoAnimActivities.contains(next)) {
anim = false;
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
} else {
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
//TRANSIT_ACTIVITY_OPEN:在同一task中在最頂端打開一個窗口
}
}
if (anim) {
next.applyOptionsLocked();//啟動動畫
} else {
next.clearOptionsLocked();
}
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity’s application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
//查詢是否已經存在滿足要求的進程
r.task.stack.setLaunchTime(r);//設置啟動時間
//如果該進程存在並且已經向ams注冊
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0//FLAG_MULTIPROCESS 可以在多進程運行的話。就不需要
//重新啟動進程
|| !”android”.equals(r.info.packageName)) {
// Don’t add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn’t make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);//啟動這個進程
return;
} catch (RemoteException e) {
Slog.w(TAG, “Exception when starting activity ”
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
ProcessRecord app;
if (!isolated) {//是否單獨進程
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
…….
if (app == null) {
//在ActivityManagerService中為新進程創建一個ProcessRecord實例
app = newProcessRecordLocked(info, processName, isolated);
if (app == null) {
Slog.w(TAG, “Failed making new process record for ”
+ processName + “/” + info.uid + ” isolated=” + isolated);
return null;
}
mProcessNames.put(processName, app.uid, app);//添加到進程列表中
if (isolated) {
mIsolatedProcesses.put(app.uid, app);//添加到單獨進程列表中
}
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, mProcessStats);
}//添加包名到 當前進程包列表
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
//當app的pid大於0並且pid不是AMS的話,就要把當前pid的進程從mPidsSelfLocked列表中移除,防止重復,因為後面我們還要加入
if (app.pid > 0 && app.pid != MY_PID) {
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
//PROC_START_TIMEOUT_MSG消息,這個消息是AMS用來控制app啟動時間的,如果啟動超時了就發出效果消息,下面我們會設置這個消息,現在需要取消之前設置的消息,防止干擾。
//接下來的邏輯:
}
app.setPid(0);//pid 置位0
//系統中所有應用進程(同時包括SystemServer)的ProcessRecord信息都保存在mPidsSelfLocked成員中
}
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
"startProcessLocked removing on hold: " + app);
mProcessesOnHold.remove(app);
//mProcessesOnHold用於保存那些在系統還沒有准備好就提前請求啟動的ProcessRecord
public static ActivityThread systemMain() {
HardwareRenderer.disable(true);
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
public final void installSystemProviders(List providers) {
if (providers != null) {
installContentProviders(mInitialApplication, providers);
}
}
public int getIntCoreSetting(String key, int defaultValue) {
synchronized (mResourcesManager) {
if (mCoreSettings != null) {
return mCoreSettings.getInt(key, defaultValue);
}
return defaultValue;
}
}
private static class EventLoggingReporter implements EventLogger.Reporter {
@Override
public void report (int code, Object... list) {
EventLog.writeEvent(code, list);
}
}
private class DropBoxReporter implements DropBox.Reporter {
private DropBoxManager dropBox;
public DropBoxReporter() {
dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
}
@Override
public void addData(String tag, byte[] data, int flags) {
dropBox.addData(tag, data, flags);
}
@Override
public void addText(String tag, String data) {
dropBox.addText(tag, data);
}
}
public static void main(String[] args) {
/// M: Retrieve the information from AMS @{
if ( args != null && args.length == 4 ) {
if ( args[0].equals("enable") ) {
mEnableAppLaunchLog = true;
}
if ( args[1].equals("true") ) {
mIsUserBuild = true;
}
if ( args[2].equals("true") ) {
mBooted = true;
}
if (args.length >=4 && args[3].equals("true") ) {//Prevention args.length < 4, then exception.
mEnableLooperLog = true;
}
if (!mIsUserBuild) {
Slog.v(TAG, "MAIN-ARGS launch log: " + mEnableAppLaunchLog + ", user build: "
+ mIsUserBuild + ", booted: " + mBooted + ", looper log: " + mEnableLooperLog);
}
}
/// @}
logAppLaunchTime(TAG, "ActivityThread is created"); /// M: It's for debugging App Launch time
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());
Security.addProvider(new AndroidKeyStoreProvider());
Process.setArgV0("");//這只進程名字
Looper.prepareMainLooper();//准備主線程消息循環
ActivityThread thread = new ActivityThread();//創建一個ActivityThread對象
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
/// M: ALPS00270724 message history mechanism @{
/// M: for build type revise @{
try {
/// M: Enable/disable ANR mechanism from adb command @{
if ( ENABLE_ALL_ANR_MECHANISM == Settings.System.getInt(mSystemContext.getContentResolver(), Settings.System.ANR_DEBUGGING_MECHANISM, 0)) {
//if(!IS_USER_BUILD){
/// M: for build type revise @}
ANRAppManager mANRAppManager = ANRAppManager.getDefault();
Looper.myLooper().setMessageLogging(mANRAppManager.newMessageLogger(mEnableLooperLog));
}
} catch (Exception e) {
Log.d(TAG, "set ANR debugging mechanism state fair " + e );
}
/// @}
/// M: Enable/disable ANR mechanism from adb command @}
Looper.loop();//主線程循環
throw new RuntimeException("Main thread loop unexpectedly exited");
}
UserHandle.myUserId());
//設置DDMS中臨時現實的進程名.
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
logAppLaunchTime(TAG, "attachApplication -> AMS"); /// M: It's for debugging App Launch time
mgr.attachApplication(mAppThread);
//調用AMS的attachApplication,mAppThread為ApplicationThread類型,
//它是應用進程和AMS交互的接口
} catch (RemoteException ex) {
// Ignore
}
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
context.init(getSystemContext().mPackageInfo, null, this);
Application app = Instrumentation.newApplication(Application.class, context);
mAllApplications.add(app);
mInitialApplication = app;
app.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);//根據pid查找對應 processrecord對象
}
} else {
app = null;
}
//如果該應用進程由AMS啟動,則它一定在AMS中有對應的processrecord,先創建一個processrecord對象
//,才發命令給zygote.如果此處app==null,則表示AMS沒有該進程的記錄。需要殺死他
if (app == null) {
Slog.w(TAG, “No pending application record for pid ” + pid
+ ” (IApplicationThread ” + thread + “); dropping process”);
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
} else {//說明是system_server進程。
try {
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}
// If this application record is still attached to a previous
// process, clean it up now.
//對象不為空,表示該進程為舊的未被殺死的進程,系統不會重用
//,而是調用 handleAppDiedLocked() 處理.將app之前的各種connect 斷開
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
} else {
app = null;
}
//如果該應用進程由AMS啟動,則它一定在AMS中有對應的processrecord,先創建一個processrecord對象
//,才發命令給zygote.如果此處app==null,則表示AMS沒有該進程的記錄。需要殺死他
if (app == null) {
Slog.w(TAG, “No pending application record for pid ” + pid
+ ” (IApplicationThread ” + thread + “); dropping process”);
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
} else {//說明是system_server進程。
try {
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}
// If this application record is still attached to a previous
// process, clean it up now.
//對象不為空,表示該進程為舊的未被殺死的進程,系統不會重用
//,而是調用 handleAppDiedLocked() 處理.將app之前的各種connect 斷開
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
// Tell the process all about itself.
if (localLOGV) Slog.v(
TAG, "Binding process pid " + pid + " to record " + app);
final String processName = app.processName;
try {
/*
創建一個應用進程訃告接收對象。當應用進程退出時,該對象的binderDied將被調
用。這樣,AMS就能做相應處理。binderDied函數將在另外一個線程中執行,其內部也會
調用handleAppDiedLocked。假如用戶在binderDied被調用之前又啟動一個進程,
那麼就會出現以上代碼中app.thread不為null的情況。這是多線程環境中常出現的
情況,不熟悉多線程編程的讀者要仔細體會。
*/
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
//設置該進程的調度優先級和oom_adj等成員
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = -100;
app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground = null;
app.foregroundServices = false;
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
//啟動成功,從消息隊列中撤銷PROC_START_TIMEOUT_MSG消息
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
“`
設置代表該應用進程的ProcessRecrod對象的一些成員變量,例如用於和應用進程交互的thread對象、進程調度優先級及oom_adj的值等。
· 從消息隊列中撤銷PROC_START_TIMEOUT_MSG。
至此,該進程啟動成功,但是這一階段的工作僅針對進程本身(如設置調度優先級,oom_adj等),還沒有涉及和Activity啟動相關的內容,這部分工作將在第二階段完成。
最近有一段時間沒寫博客了,一方面是工作比較忙,一方面也著實本人水平有限,沒有太多能與大家分享的東西,也就是在最近公司要做一個搶紅包的功能,老板發話了咋們就開干呗,本人就開
效果圖點擊標簽,指示線滑動到當前的標簽下。 用到的技術: activity中添加 fragement, ViewPager, 自定義繪制view-Activity中動態添
為了解決65535方法數超標的問題,Google推薦使用MultiDex來加載classes2.dex,classes3.dex等等,其基本思想就是在運行時動態修改Cla
多虧了<include />標簽,在Android裡,很容易就能做到共享和重用UI組件。在Android開發中,很容易就能創建出復雜的UI結構,結果呢,用了很