Android應用程序的啓動過程

前言

在Android系統中,Activity和Service是應用程序的核心組件,它們以鬆藕合的方式組合在一起構成了一個完整的應用程序,這得益於應用程序框架層提供了一套完整的機制來協助應用程序啓動這些Activity和Service,以及提供Binder機制幫助它們相互間進行通信。

在Android系統中,有兩種操作會引發Activity的啓動,一種用戶點擊應用程序圖標時,Launcher會爲我們啓動應用程序的主Activity;應用程序的默認Activity啓動起來後,它又可以在內部通過調用startActvity接口啓動新的Activity,依此類推,每一個Activity都可以在內部啓動新的Activity。通過這種連鎖反應,按需啓動Activity,從而完成應用程序的功能。

這裏,我們通過一個具體的例子來說明如何啓動Android應用程序的Activity。Activity的啓動方式有兩種,一種是顯式的,一種是隱式的,隱式啓動可以使得Activity之間的藕合性更加鬆散,因此,這裏只關注隱式啓動Activity的方法。

  • MainActivity的啓動過程如下圖所示:.

這裏寫圖片描述


簡要流程

在這裏插入圖片描述
① 點擊桌面App圖標,Launcher進程採用Binder IPC向system_server進程發起startActivity請求;

② system_server進程接收到請求後,向zygote進程發送創建進程的請求;

③ Zygote進程fork出新的子進程,即App進程;

④ App進程,通過Binder IPC向sytem_server進程發起attachApplication請求;

⑤ system_server進程在收到請求後,進行一系列準備工作後,再通過binder IPC向App進程發送scheduleLaunchActivity請求;

⑥ App進程的binder線程(ApplicationThread)在收到請求後,通過handler向主線程發送LAUNCH_ACTIVITY消息;

⑦ 主線程在收到Message後,通過發射機制創建目標Activity,並回調Activity.onCreate()等方法。

⑧ 到此,App便正式啓動,開始進入Activity生命週期,執行完onCreate/onStart/onResume方法,UI渲染結束後便可以看到App的主界面。


具體流程

Step 1. Launcher.startActivitySafely

在Android系統中,應用程序是由Launcher啓動起來的,其實,Launcher本身也是一個應用程序,其它的應用程序安裝後,就會Launcher的界面上出現一個相應的圖標,點擊這個圖標時,Launcher就會對應的應用程序啓動起來。

Launcher的源代碼工程在packages/apps/Launcher2目錄下,負責啓動其它應用程序的源代碼實現在src/com/android/launcher2/Launcher.java文件中:

/**
* Default launcher application.
*/
public final class Launcher extends Activity
		implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
 
	......
 
	/**
	* Launches the intent referred by the clicked shortcut.
	*
	* @param v The view representing the clicked shortcut.
	*/
	public void onClick(View v) {
		Object tag = v.getTag();
		if (tag instanceof ShortcutInfo) {
			// Open shortcut
			final Intent intent = ((ShortcutInfo) tag).intent;
			int[] pos = new int[2];
			v.getLocationOnScreen(pos);
			intent.setSourceBounds(new Rect(pos[0], pos[1],
				pos[0] + v.getWidth(), pos[1] + v.getHeight()));
			startActivitySafely(intent, tag);
		} else if (tag instanceof FolderInfo) {
			......
		} else if (v == mHandleView) {
			......
		}
	}
 
	void startActivitySafely(Intent intent, Object tag) {
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		try {
			startActivity(intent);
		} catch (ActivityNotFoundException e) {
			......
		} catch (SecurityException e) {
			......
		}
	}
 
	......
 
}

它的默認Activity是MainActivity,這裏是AndroidManifest.xml文件中配置的:

<activity android:name=".MainActivity"  
      android:label="@string/app_name">  
       <intent-filter>  
        <action android:name="android.intent.action.MAIN" />  
        <category android:name="android.intent.category.LAUNCHER" />  
    </intent-filter>  
</activity>  

因此,這裏的intent包含的信息爲:action = “android.intent.action.Main”,category=“android.intent.category.LAUNCHER”, cmp=“shy.luo.activity/.MainActivity”,表示它要啓動的Activity爲shy.luo.activity.MainActivity。Intent.FLAG_ACTIVITY_NEW_TASK表示要在一個新的Task中啓動這個Activity,注意,Task是Android系統中的概念,它不同於進程Process的概念。簡單地說,一個Task是一系列Activity的集合,這個集合是以堆棧的形式來組織的,遵循後進先出的原則。事實上,Task是一個非常複雜的概念,有興趣的讀者可以到官網查看相關的資料。這裏,我們只要知道,這個MainActivity要在一個新的Task中啓動就可以了。


Step 2. Activity.startActivity

在Step 1中,我們看到,Launcher繼承於Activity類,而Activity類實現了startActivity函數,因此,這裏就調用了Activity.startActivity函數,它實現在frameworks/base/core/java/android/app/Activity.java文件中:


public class Activity extends ContextThemeWrapper
		implements LayoutInflater.Factory,
		Window.Callback, KeyEvent.Callback,
		OnCreateContextMenuListener, ComponentCallbacks {
 
	......
 
	@Override
	public void startActivity(Intent intent) {
		startActivityForResult(intent, -1);
	}
 
	......
 
}

這個函數實現很簡單,它調用startActivityForResult來進一步處理,第二個參數傳入-1表示不需要這個Actvity結束後的返回結果。


Step 3. Activity.startActivityForResult

這個函數也是實現在frameworks/base/core/java/android/app/Activity.java文件中:


public class Activity extends ContextThemeWrapper
		implements LayoutInflater.Factory,
		Window.Callback, KeyEvent.Callback,
		OnCreateContextMenuListener, ComponentCallbacks {
 
	......
 
	public void startActivityForResult(Intent intent, int requestCode) {
		if (mParent == null) {
			Instrumentation.ActivityResult ar =
				mInstrumentation.execStartActivity(
				this, mMainThread.getApplicationThread(), mToken, this,
				intent, requestCode);
			......
		} else {
			......
		}
 
 
	......
 
}

這裏的mInstrumentation是Activity類的成員變量,它的類型是Intrumentation,定義在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用來監控應用程序和系統的交互。

這裏的mMainThread也是Activity類的成員變量,它的類型是ActivityThread,它代表的是應用程序的主線程。這裏通過mMainThread.getApplicationThread獲得它裏面的ApplicationThread成員變量,它是一個Binder對象,後面我們會看到,ActivityManagerService會使用它來和ActivityThread來進行進程間通信。這裏我們需注意的是,這裏的mMainThread代表的是Launcher應用程序運行的進程。

這裏的mToken也是Activity類的成員變量,它是一個Binder對象的遠程接口。


Step 4. Instrumentation.execStartActivity

這個函數定義在frameworks/base/core/java/android/app/Instrumentation.java文件中:

public class Instrumentation {
 
	......
 
	public ActivityResult execStartActivity(
	Context who, IBinder contextThread, IBinder token, Activity target,
	Intent intent, int requestCode) {
		IApplicationThread whoThread = (IApplicationThread) contextThread;
		if (mActivityMonitors != null) {
			......
		}
		try {
			int result = ActivityManagerNative.getDefault()
				.startActivity(whoThread, intent,
				intent.resolveTypeIfNeeded(who.getContentResolver()),
				null, 0, token, target != null ? target.mEmbeddedID : null,
				requestCode, false, false);
			......
		} catch (RemoteException e) {
		}
		return null;
	}
 
	......
 
}

這裏的ActivityManagerNative.getDefault返回ActivityManagerService的遠程接口,即ActivityManagerProxy接口。

這裏的intent.resolveTypeIfNeeded返回這個intent的MIME類型,在這個例子中,沒有AndroidManifest.xml設置MainActivity的MIME類型,因此,這裏返回null。

這裏的target不爲null,但是target.mEmbddedID爲null,我們不用關注。


Step 5. ActivityManagerProxy.startActivity

這個函數定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

class ActivityManagerProxy implements IActivityManager
{
 
	......
 
	public int startActivity(IApplicationThread caller, Intent intent,
			String resolvedType, Uri[] grantedUriPermissions, int grantedMode,
			IBinder resultTo, String resultWho,
			int requestCode, boolean onlyIfNeeded,
			boolean debug) throws RemoteException {
		Parcel data = Parcel.obtain();
		Parcel reply = Parcel.obtain();
		data.writeInterfaceToken(IActivityManager.descriptor);
		data.writeStrongBinder(caller != null ? caller.asBinder() : null);
		intent.writeToParcel(data, 0);
		data.writeString(resolvedType);
		data.writeTypedArray(grantedUriPermissions, 0);
		data.writeInt(grantedMode);
		data.writeStrongBinder(resultTo);
		data.writeString(resultWho);
		data.writeInt(requestCode);
		data.writeInt(onlyIfNeeded ? 1 : 0);
		data.writeInt(debug ? 1 : 0);
		mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
		reply.readException();
		int result = reply.readInt();
		reply.recycle();
		data.recycle();
		return result;
	}
 
	......
 
}

這裏的參數比較多,我們先整理一下。從上面的調用可以知道,這裏的參數resolvedType、grantedUriPermissions和resultWho均爲null;參數caller爲ApplicationThread類型的Binder實體;參數resultTo爲一個Binder實體的遠程接口,我們先不關注它;參數grantedMode爲0,我們也先不關注它;參數requestCode爲-1;參數onlyIfNeeded和debug均空false。


Step 6. ActivityManagerService.startActivity

上一步Step 5通過Binder驅動程序就進入到ActivityManagerService的startActivity函數來了,它定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	public final int startActivity(IApplicationThread caller,
			Intent intent, String resolvedType, Uri[] grantedUriPermissions,
			int grantedMode, IBinder resultTo,
			String resultWho, int requestCode, boolean onlyIfNeeded,
			boolean debug) {
		return mMainStack.startActivityMayWait(caller, intent, resolvedType,
			grantedUriPermissions, grantedMode, resultTo, resultWho,
			requestCode, onlyIfNeeded, debug, null, null);
	}
 
 
	......
 
}

這裏只是簡單地將操作轉發給成員變量mMainStack的startActivityMayWait函數,這裏的mMainStack的類型爲ActivityStack。


Step 7. ActivityStack.startActivityMayWait

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:


public class ActivityStack {
 
	......
 
	final int startActivityMayWait(IApplicationThread caller,
			Intent intent, String resolvedType, Uri[] grantedUriPermissions,
			int grantedMode, IBinder resultTo,
			String resultWho, int requestCode, boolean onlyIfNeeded,
			boolean debug, WaitResult outResult, Configuration config) {
 
		......
 
		boolean componentSpecified = intent.getComponent() != null;
 
		// Don't modify the client's object!
		intent = new Intent(intent);
 
		// Collect information about the target of the Intent.
		ActivityInfo aInfo;
		try {
			ResolveInfo rInfo =
				AppGlobals.getPackageManager().resolveIntent(
				intent, resolvedType,
				PackageManager.MATCH_DEFAULT_ONLY
				| ActivityManagerService.STOCK_PM_FLAGS);
			aInfo = rInfo != null ? rInfo.activityInfo : null;
		} catch (RemoteException e) {
			......
		}
 
		if (aInfo != null) {
			// Store the found target back into the intent, because now that
			// we have it we never want to do this again.  For example, if the
			// user navigates back to this point in the history, we should
			// always restart the exact same activity.
			intent.setComponent(new ComponentName(
				aInfo.applicationInfo.packageName, aInfo.name));
			......
		}
 
		synchronized (mService) {
			int callingPid;
			int callingUid;
			if (caller == null) {
				......
			} else {
				callingPid = callingUid = -1;
			}
 
			mConfigWillChange = config != null
				&& mService.mConfiguration.diff(config) != 0;
 
			......
 
			if (mMainStack && aInfo != null &&
				(aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
				  
		              ......
 
			}
 
			int res = startActivityLocked(caller, intent, resolvedType,
				grantedUriPermissions, grantedMode, aInfo,
				resultTo, resultWho, requestCode, callingPid, callingUid,
				onlyIfNeeded, componentSpecified);
 
			if (mConfigWillChange && mMainStack) {
				......
			}
 
			......
 
			if (outResult != null) {
				......
			}
 
			return res;
		}
 
	}
 
	......
 
}

注意,從Step 6傳下來的參數outResult和config均爲null,此外,表達式(aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0爲false,因此,這裏忽略了無關代碼。

下面語句對參數intent的內容進行解析,得到MainActivity的相關信息,保存在aInfo變量中:

 ActivityInfo aInfo;
    try {
	ResolveInfo rInfo =
	AppGlobals.getPackageManager().resolveIntent(
		intent, resolvedType,
		PackageManager.MATCH_DEFAULT_ONLY
		| ActivityManagerService.STOCK_PM_FLAGS);
	aInfo = rInfo != null ? rInfo.activityInfo : null;
    } catch (RemoteException e) {
		......
    }

解析之後,得到的aInfo.applicationInfo.packageName的值爲"shy.luo.activity",aInfo.name的值爲"shy.luo.activity.MainActivity",這是在這個實例的配置文件AndroidManifest.xml裏面配置的。

此外,函數開始的地方調用intent.getComponent()函數的返回值不爲null,因此,這裏的componentSpecified變量爲true。


Step 8. ActivityStack.startActivityLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	final int startActivityLocked(IApplicationThread caller,
		    Intent intent, String resolvedType,
		    Uri[] grantedUriPermissions,
		    int grantedMode, ActivityInfo aInfo, IBinder resultTo,
	            String resultWho, int requestCode,
		    int callingPid, int callingUid, boolean onlyIfNeeded,
		    boolean componentSpecified) {
	        int err = START_SUCCESS;
 
		ProcessRecord callerApp = null;
		if (caller != null) {
			callerApp = mService.getRecordForAppLocked(caller);
			if (callerApp != null) {
				callingPid = callerApp.pid;
				callingUid = callerApp.info.uid;
			} else {
				......
			}
		}
 
		......
 
		ActivityRecord sourceRecord = null;
		ActivityRecord resultRecord = null;
		if (resultTo != null) {
			int index = indexOfTokenLocked(resultTo);
			
			......
				
			if (index >= 0) {
				sourceRecord = (ActivityRecord)mHistory.get(index);
				if (requestCode >= 0 && !sourceRecord.finishing) {
					......
				}
			}
		}
 
		int launchFlags = intent.getFlags();
 
		if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
			&& sourceRecord != null) {
			......
		}
 
		if (err == START_SUCCESS && intent.getComponent() == null) {
			......
		}
 
		if (err == START_SUCCESS && aInfo == null) {
			......
		}
 
		if (err != START_SUCCESS) {
			......
		}
 
		......
 
		ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
			intent, resolvedType, aInfo, mService.mConfiguration,
			resultRecord, resultWho, requestCode, componentSpecified);
 
		......
 
		return startActivityUncheckedLocked(r, sourceRecord,
			grantedUriPermissions, grantedMode, onlyIfNeeded, true);
	}
 
 
	......
 
}

從傳進來的參數caller得到調用者的進程信息,並保存在callerApp變量中,這裏就是Launcher應用程序的進程信息了。

前面說過,參數resultTo是Launcher這個Activity裏面的一個Binder對象,通過它可以獲得Launcher這個Activity的相關信息,保存在sourceRecord變量中。

再接下來,創建即將要啓動的Activity的相關信息,並保存在r變量中:

ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
	intent, resolvedType, aInfo, mService.mConfiguration,
	resultRecord, resultWho, requestCode, componentSpecified);

接着調用startActivityUncheckedLocked函數進行下一步操作。


Step 9. ActivityStack.startActivityUncheckedLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

 public class ActivityStack {
 
	......
 
	final int startActivityUncheckedLocked(ActivityRecord r,
		ActivityRecord sourceRecord, Uri[] grantedUriPermissions,
		int grantedMode, boolean onlyIfNeeded, boolean doResume) {
		final Intent intent = r.intent;
		final int callingUid = r.launchedFromUid;
 
		int launchFlags = intent.getFlags();
 
		// We'll invoke onUserLeaving before onPause only if the launching
		// activity did not explicitly state that this is an automated launch.
		mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
		
		......
 
		ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
			!= 0 ? r : null;
 
		// If the onlyIfNeeded flag is set, then we can do this if the activity
		// being launched is the same as the one making the call...  or, as
		// a special case, if we do not know the caller then we count the
		// current top activity as the caller.
		if (onlyIfNeeded) {
			......
		}
 
		if (sourceRecord == null) {
			......
		} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
			......
		} else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
			|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
			......
		}
 
		if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
			......
		}
 
		boolean addingToTask = false;
		if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
			(launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
			|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
			|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
				// If bring to front is requested, and no result is requested, and
				// we can find a task that was started with this same
				// component, then instead of launching bring that one to the front.
				if (r.resultTo == null) {
					// See if there is a task to bring to the front.  If this is
					// a SINGLE_INSTANCE activity, there can be one and only one
					// instance of it in the history, and it is always in its own
					// unique task, so we do a special search.
					ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
						? findTaskLocked(intent, r.info)
						: findActivityLocked(intent, r.info);
					if (taskTop != null) {
						......
					}
				}
		}
 
		......
 
		if (r.packageName != null) {
			// If the activity being launched is the same as the one currently
			// at the top, then we need to check if it should only be launched
			// once.
			ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
			if (top != null && r.resultTo == null) {
				if (top.realActivity.equals(r.realActivity)) {
					......
				}
			}
 
		} else {
			......
		}
 
		boolean newTask = false;
 
		// Should this be considered a new task?
		if (r.resultTo == null && !addingToTask
			&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
				// todo: should do better management of integers.
				mService.mCurTask++;
				if (mService.mCurTask <= 0) {
					mService.mCurTask = 1;
				}
				r.task = new TaskRecord(mService.mCurTask, r.info, intent,
					(r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
				......
				newTask = true;
				if (mMainStack) {
					mService.addRecentTaskLocked(r.task);
				}
 
		} else if (sourceRecord != null) {
			......
		} else {
			......
		}
 
		......
 
		startActivityLocked(r, newTask, doResume);
		return START_SUCCESS;
	}
 
	......
 
}

函數首先獲得intent的標誌值,保存在launchFlags變量中。

這個intent的標誌值的位Intent.FLAG_ACTIVITY_NO_USER_ACTION沒有置位,因此 ,成員變量mUserLeaving的值爲true。

這個intent的標誌值的位Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP也沒有置位,因此,變量notTop的值爲null。

由於在這個例子的AndroidManifest.xml文件中,MainActivity沒有配置launchMode屬值,因此,這裏的r.launchMode爲默認值0,表示以標準(Standard,或者稱爲ActivityInfo.LAUNCH_MULTIPLE)的方式來啓動這個Activity。Activity的啓動方式有四種,其餘三種分別是ActivityInfo.LAUNCH_SINGLE_INSTANCE、ActivityInfo.LAUNCH_SINGLE_TASK和ActivityInfo.LAUNCH_SINGLE_TOP,具體可以參考官方網站

傳進來的參數r.resultTo爲null,表示Launcher不需要等這個即將要啓動的MainActivity的執行結果。

由於這個intent的標誌值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK沒有置位,因此,下面的if語句會被執行:

	if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
	(launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
	|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
	|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
		// If bring to front is requested, and no result is requested, and
		// we can find a task that was started with this same
		// component, then instead of launching bring that one to the front.
		if (r.resultTo == null) {
			// See if there is a task to bring to the front.  If this is
			// a SINGLE_INSTANCE activity, there can be one and only one
			// instance of it in the history, and it is always in its own
			// unique task, so we do a special search.
			ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
				? findTaskLocked(intent, r.info)
				: findActivityLocked(intent, r.info);
			if (taskTop != null) {
				......
			}
		}
    }

這段代碼的邏輯是查看一下,當前有沒有Task可以用來執行這個Activity。由於r.launchMode的值不爲ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通過findTaskLocked函數來查找存不存這樣的Task,這裏返回的結果是null,即taskTop爲null,因此,需要創建一個新的Task來啓動這個Activity。

接着往下看:

	if (r.packageName != null) {
	// If the activity being launched is the same as the one currently
	// at the top, then we need to check if it should only be launched
	// once.
	ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
	if (top != null && r.resultTo == null) {
		if (top.realActivity.equals(r.realActivity)) {
			......
			}
		}
 
    }

這段代碼的邏輯是看一下,當前在堆棧頂端的Activity是否就是即將要啓動的Activity,有些情況下,如果即將要啓動的Activity就在堆棧的頂端,那麼,就不會重新啓動這個Activity的別一個實例了,具體可以參考官方網站。現在處理堆棧頂端的Activity是Launcher,與我們即將要啓動的MainActivity不是同一個Activity,因此,這裏不用進一步處理上述介紹的情況。

執行到這裏,我們知道,要在一個新的Task裏面來啓動這個Activity了,於是新創建一個Task:

   if (r.resultTo == null && !addingToTask
	&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
	// todo: should do better management of integers.
	mService.mCurTask++;
	if (mService.mCurTask <= 0) {
		mService.mCurTask = 1;
	}
	r.task = new TaskRecord(mService.mCurTask, r.info, intent,
		(r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
	......
	newTask = true;
	if (mMainStack) {
		mService.addRecentTaskLocked(r.task);
	}
 
    }

新建的Task保存在r.task域中,同時,添加到mService中去,這裏的mService就是ActivityManagerService了。

最後就進入startActivityLocked(r, newTask, doResume)進一步處理了。這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	private final void startActivityLocked(ActivityRecord r, boolean newTask,
			boolean doResume) {
		final int NH = mHistory.size();
 
		int addPos = -1;
 
		if (!newTask) {
			......
		}
 
		// Place a new activity at top of stack, so it is next to interact
		// with the user.
		if (addPos < 0) {
			addPos = NH;
		}
 
		// If we are not placing the new activity frontmost, we do not want
		// to deliver the onUserLeaving callback to the actual frontmost
		// activity
		if (addPos < NH) {
			......
		}
 
		// Slot the activity into the history stack and proceed
		mHistory.add(addPos, r);
		r.inHistory = true;
		r.frontOfTask = newTask;
		r.task.numActivities++;
		if (NH > 0) {
			// We want to show the starting preview window if we are
			// switching to a new task, or the next activity's process is
			// not currently running.
			......
		} else {
			// If this is the first activity, don't do any fancy animations,
			// because there is nothing for it to animate on top of.
			......
		}
		
		......
 
		if (doResume) {
			resumeTopActivityLocked(null);
		}
	}
 
	......
 
}

這裏的NH表示當前系統中歷史任務的個數,這裏肯定是大於0,因爲Launcher已經跑起來了。當NH>0時,並且現在要切換新任務時,要做一些任務切的界面操作,這段代碼我們就不看了,這裏不會影響到下面啓Activity的過程,有興趣的讀取可以自己研究一下。

這裏傳進來的參數doResume爲true,於是調用resumeTopActivityLocked進一步操作。


Step 10. Activity.resumeTopActivityLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	/**
	* Ensure that the top activity in the stack is resumed.
	*
	* @param prev The previously resumed activity, for when in the process
	* of pausing; can be null to call from elsewhere.
	*
	* @return Returns true if something is being resumed, or false if
	* nothing happened.
	*/
	final boolean resumeTopActivityLocked(ActivityRecord prev) {
		// 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 = mUserLeaving;
		mUserLeaving = false;
 
		if (next == null) {
			......
		}
 
		next.delayedResume = false;
 
		// If the top activity is the resumed one, nothing to do.
		if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
			......
		}
 
		// If we are sleeping, and there is no resumed activity, and the top
		// activity is paused, well that is the state we want.
		if ((mService.mSleeping || mService.mShuttingDown)
			&& mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
			......
		}
 
		......
 
		// If we are currently pausing an activity, then don't do anything
		// until that is done.
		if (mPausingActivity != null) {
			......
		}
 
		......
 
		// We need to start pausing the current activity so the top one
		// can be resumed...
		if (mResumedActivity != null) {
			......
			startPausingLocked(userLeaving, false);
			return true;
		}
 
		......
	}
 
	......
 
}

函數先通過調用topRunningActivityLocked函數獲得堆棧頂端的Activity,這裏就是MainActivity了,這是在上面的Step 9設置好的,保存在next變量中。

接下來把mUserLeaving的保存在本地變量userLeaving中,然後重新設置爲false,在上面的Step 9中,mUserLeaving的值爲true,因此,這裏的userLeaving爲true。

這裏的mResumedActivity爲Launcher,因爲Launcher是當前正被執行的Activity。

當我們處理休眠狀態時,mLastPausedActivity保存堆棧頂端的Activity,因爲當前不是休眠狀態,所以mLastPausedActivity爲null。

有了這些信息之後,下面的語句就容易理解了:

    // If the top activity is the resumed one, nothing to do.
    if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
	......
    }
 
    // If we are sleeping, and there is no resumed activity, and the top
    // activity is paused, well that is the state we want.
    if ((mService.mSleeping || mService.mShuttingDown)
	&& mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
	......
    }

它首先看要啓動的Activity是否就是當前處理Resumed狀態的Activity,如果是的話,那就什麼都不用做,直接返回就可以了;否則再看一下系統當前是否休眠狀態,如果是的話,再看看要啓動的Activity是否就是當前處於堆棧頂端的Activity,如果是的話,也是什麼都不用做。

上面兩個條件都不滿足,因此,在繼續往下執行之前,首先要把當處於Resumed狀態的Activity推入Paused狀態,然後纔可以啓動新的Activity。但是在將當前這個Resumed狀態的Activity推入Paused狀態之前,首先要看一下當前是否有Activity正在進入Pausing狀態,如果有的話,當前這個Resumed狀態的Activity就要稍後才能進入Paused狀態了,這樣就保證了所有需要進入Paused狀態的Activity串行處理。

這裏沒有處於Pausing狀態的Activity,即mPausingActivity爲null,而且mResumedActivity也不爲null,於是就調用startPausingLocked函數把Launcher推入Paused狀態去了。


Step 11. ActivityStack.startPausingLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
		if (mPausingActivity != null) {
			......
		}
		ActivityRecord prev = mResumedActivity;
		if (prev == null) {
			......
		}
		......
		mResumedActivity = null;
		mPausingActivity = prev;
		mLastPausedActivity = prev;
		prev.state = ActivityState.PAUSING;
		......
 
		if (prev.app != null && prev.app.thread != null) {
			......
			try {
				......
				prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
					prev.configChangeFlags);
				......
			} catch (Exception e) {
				......
			}
		} else {
			......
		}
 
		......
	
	}
 
	......
 
}

函數首先把mResumedActivity保存在本地變量prev中。在上一步Step 10中,說到mResumedActivity就是Launcher,因此,這裏把Launcher進程中的ApplicationThread對象取出來,通過它來通知Launcher這個Activity它要進入Paused狀態了。當然,這裏的prev.app.thread是一個ApplicationThread對象的遠程接口,通過調用這個遠程接口的schedulePauseActivity來通知Launcher進入Paused狀態。

參數prev.finishing表示prev所代表的Activity是否正在等待結束的Activity列表中,由於Laucher這個Activity還沒結束,所以這裏爲false;參數prev.configChangeFlags表示哪些config發生了變化,這裏我們不關心它的值。


Step 12. ApplicationThreadProxy.schedulePauseActivity

這個函數定義在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

class ApplicationThreadProxy implements IApplicationThread {
	
	......
 
	public final void schedulePauseActivity(IBinder token, boolean finished,
	boolean userLeaving, int configChanges) throws RemoteException {
		Parcel data = Parcel.obtain();
		data.writeInterfaceToken(IApplicationThread.descriptor);
		data.writeStrongBinder(token);
		data.writeInt(finished ? 1 : 0);
		data.writeInt(userLeaving ? 1 :0);
		data.writeInt(configChanges);
		mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
			IBinder.FLAG_ONEWAY);
		data.recycle();
	}
 
	......
 
}

這個函數通過Binder進程間通信機制進入到ApplicationThread.schedulePauseActivity函數中。


Step 13. ApplicationThread.schedulePauseActivity

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中,它是ActivityThread的內部類:


public final class ActivityThread {
	
	......
 
	private final class ApplicationThread extends ApplicationThreadNative {
		
		......
 
		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);
		}
 
		......
 
	}
 
	......
 
}

這裏調用的函數queueOrSendMessage是ActivityThread類的成員函數。

上面說到,這裏的finished值爲false,因此,queueOrSendMessage的第一個參數值爲H.PAUSE_ACTIVITY,表示要暫停token所代表的Activity,即Launcher。


###Step 14. ActivityThread.queueOrSendMessage

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final void queueOrSendMessage(int what, Object obj, int arg1) {
		queueOrSendMessage(what, obj, arg1, 0);
	}
 
	private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
		synchronized (this) {
			......
			Message msg = Message.obtain();
			msg.what = what;
			msg.obj = obj;
			msg.arg1 = arg1;
			msg.arg2 = arg2;
			mH.sendMessage(msg);
		}
	}
 
	......
 
}

這裏首先將相關信息組裝成一個msg,然後通過mH成員變量發送出去,mH的類型是H,繼承於Handler類,是ActivityThread的內部類,因此,這個消息最後由H.handleMessage來處理。


###Step 15. H.handleMessage

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final class H extends Handler {
 
		......
 
		public void handleMessage(Message msg) {
			......
			switch (msg.what) {
			
			......
			
			case PAUSE_ACTIVITY:
				handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
				maybeSnapshot();
				break;
 
			......
 
			}
		......
 
	}
 
	......
 
}

這裏調用ActivityThread.handlePauseActivity進一步操作,msg.obj是一個ActivityRecord對象的引用,它代表的是Launcher這個Activity。


###Step 16. ActivityThread.handlePauseActivity

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final 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;
			Bundle state = performPauseActivity(token, finished, true);
 
			// Make sure any pending writes are now committed.
			QueuedWork.waitToFinish();
 
			// Tell the activity manager we have paused.
			try {
				ActivityManagerNative.getDefault().activityPaused(token, state);
			} catch (RemoteException ex) {
			}
		}
	}
 
	......
 
}

函數首先將Binder引用token轉換成ActivityRecord的遠程接口ActivityClientRecord,然後做了三個事情:1. 如果userLeaving爲true,則通過調用performUserLeavingActivity函數來調用Activity.onUserLeaveHint通知Activity,用戶要離開它了;2. 調用performPauseActivity函數來調用Activity.onPause函數,我們知道,在Activity的生命週期中,當它要讓位於其它的Activity時,系統就會調用它的onPause函數;3. 它通知ActivityManagerService,這個Activity已經進入Paused狀態了,ActivityManagerService現在可以完成未竟的事情,即啓動MainActivity了。


###Step 17. ActivityManagerProxy.activityPaused

這個函數定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

class ActivityManagerProxy implements IActivityManager
{
	......
 
	public void activityPaused(IBinder token, Bundle state) throws RemoteException
	{
		Parcel data = Parcel.obtain();
		Parcel reply = Parcel.obtain();
		data.writeInterfaceToken(IActivityManager.descriptor);
		data.writeStrongBinder(token);
		data.writeBundle(state);
		mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
		reply.readException();
		data.recycle();
		reply.recycle();
	}
 
	......
 
}

這裏通過Binder進程間通信機制就進入到ActivityManagerService.activityPaused函數中去了。


###Step 18. ActivityManagerService.activityPaused

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:


public final class ActivityManagerService extends ActivityManagerNative
			implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
	......
 
	public final void activityPaused(IBinder token, Bundle icicle) {
		
		......
 
		final long origId = Binder.clearCallingIdentity();
		mMainStack.activityPaused(token, icicle, false);
		
		......
	}
 
	......
 
}

這裏,又再次進入到ActivityStack類中,執行activityPaused函數。


###Step 19. ActivityStack.activityPaused

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
		
		......
 
		ActivityRecord r = null;
 
		synchronized (mService) {
			int index = indexOfTokenLocked(token);
			if (index >= 0) {
				r = (ActivityRecord)mHistory.get(index);
				if (!timeout) {
					r.icicle = icicle;
					r.haveState = true;
				}
				mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
				if (mPausingActivity == r) {
					r.state = ActivityState.PAUSED;
					completePauseLocked();
				} else {
					......
				}
			}
		}
	}
 
	......
 
}

這裏通過參數token在mHistory列表中得到ActivityRecord,從上面我們知道,這個ActivityRecord代表的是Launcher這個Activity,而我們在Step 11中,把Launcher這個Activity的信息保存在mPausingActivity中,因此,這裏mPausingActivity等於r,於是,執行completePauseLocked操作。


Step 20. ActivityStack.completePauseLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	private final void completePauseLocked() {
		ActivityRecord prev = mPausingActivity;
		
		......
 
		if (prev != null) {
 
			......
 
			mPausingActivity = null;
		}
 
		if (!mService.mSleeping && !mService.mShuttingDown) {
			resumeTopActivityLocked(prev);
		} else {
			......
		}
 
		......
	}
 
	......
 
}

函數首先把mPausingActivity變量清空,因爲現在不需要它了,然後調用resumeTopActivityLokced進一步操作,它傳入的參數即爲代表Launcher這個Activity的ActivityRecord。


###Step 21. ActivityStack.resumeTopActivityLokced

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	final boolean resumeTopActivityLocked(ActivityRecord prev) {
		......
 
		// 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 = mUserLeaving;
		mUserLeaving = false;
 
		......
 
		next.delayedResume = false;
 
		// If the top activity is the resumed one, nothing to do.
		if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
			......
			return false;
		}
 
		// If we are sleeping, and there is no resumed activity, and the top
		// activity is paused, well that is the state we want.
		if ((mService.mSleeping || mService.mShuttingDown)
			&& mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
			......
			return false;
		}
 
		.......
 
 
		// We need to start pausing the current activity so the top one
		// can be resumed...
		if (mResumedActivity != null) {
			......
			return true;
		}
 
		......
 
 
		if (next.app != null && next.app.thread != null) {
			......
 
		} else {
			......
			startSpecificActivityLocked(next, true, true);
		}
 
		return true;
	}
 
 
	......
 
}

通過上面的Step 9,我們知道,當前在堆棧頂端的Activity爲我們即將要啓動的MainActivity,這裏通過調用topRunningActivityLocked將它取回來,保存在next變量中。之前最後一個Resumed狀態的Activity,即Launcher,到了這裏已經處於Paused狀態了,因此,mResumedActivity爲null。最後一個處於Paused狀態的Activity爲Launcher,因此,這裏的mLastPausedActivity就爲Launcher。前面我們爲MainActivity創建了ActivityRecord後,它的app域一直保持爲null。有了這些信息後,上面這段代碼就容易理解了,它最終調用startSpecificActivityLocked進行下一步操作。


Step 22. ActivityStack.startSpecificActivityLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:


public class ActivityStack {
 
	......
 
	private final 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);
 
		......
 
		if (app != null && app.thread != null) {
			try {
				realStartActivityLocked(r, app, andResume, checkConfig);
				return;
			} catch (RemoteException e) {
				......
			}
		}
 
		mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
			"activity", r.intent.getComponent(), false);
	}
 
 
	......
 
}

注意,這裏由於是第一次啓動應用程序的Activity,所以下面語句:

ProcessRecord app = mService.getProcessRecordLocked(r.processName,
	r.info.applicationInfo.uid);

取回來的app爲null。在Activity應用程序中的AndroidManifest.xml配置文件中,我們沒有指定Application標籤的process屬性,系統就會默認使用package的名稱,這裏就是"shy.luo.activity"了。每一個應用程序都有自己的uid,因此,這裏uid + process的組合就可以爲每一個應用程序創建一個ProcessRecord。當然,我們可以配置兩個應用程序具有相同的uid和package,或者在AndroidManifest.xml配置文件的application標籤或者activity標籤中顯式指定相同的process屬性值,這樣,不同的應用程序也可以在同一個進程中啓動。

函數最終執行ActivityManagerService.startProcessLocked函數進行下一步操作。


###Step 23. ActivityManagerService.startProcessLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:


public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	final ProcessRecord startProcessLocked(String processName,
			ApplicationInfo info, boolean knownToBeDead, int intentFlags,
			String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
 
		ProcessRecord app = getProcessRecordLocked(processName, info.uid);
		
		......
 
		String hostingNameStr = hostingName != null
			? hostingName.flattenToShortString() : null;
 
		......
 
		if (app == null) {
			app = new ProcessRecordLocked(null, info, processName);
			mProcessNames.put(processName, info.uid, app);
		} else {
			// If this is a new package in the process, add the package to the list
			app.addPackage(info.packageName);
		}
 
		......
 
		startProcessLocked(app, hostingType, hostingNameStr);
		return (app.pid != 0) ? app : null;
	}
 
	......
 
}

這裏再次檢查是否已經有以process + uid命名的進程存在,在我們這個情景中,返回值app爲null,因此,後面會創建一個ProcessRecord,並存保存在成員變量mProcessNames中,最後,調用另一個startProcessLocked函數進一步操作:

public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	private final void startProcessLocked(ProcessRecord app,
				String hostingType, String hostingNameStr) {
 
		......
 
		try {
			int uid = app.info.uid;
			int[] gids = null;
			try {
				gids = mContext.getPackageManager().getPackageGids(
					app.info.packageName);
			} catch (PackageManager.NameNotFoundException e) {
				......
			}
			
			......
 
			int debugFlags = 0;
			
			......
			
			int pid = Process.start("android.app.ActivityThread",
				mSimpleProcessManagement ? app.processName : null, uid, uid,
				gids, debugFlags, null);
			
			......
 
		} catch (RuntimeException e) {
			
			......
 
		}
	}
 
	......
 
}

這裏主要是調用Process.start接口來創建一個新的進程,新的進程會導入android.app.ActivityThread類,並且執行它的main函數,這就是爲什麼我們前面說每一個應用程序都有一個ActivityThread實例來對應的原因。


Step 24. ActivityThread.main

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
 
	......
 
	private final void attach(boolean system) {
		......
 
		mSystemThread = system;
		if (!system) {
 
			......
 
			IActivityManager mgr = ActivityManagerNative.getDefault();
			try {
				mgr.attachApplication(mAppThread);
			} catch (RemoteException ex) {
			}
		} else {
 
			......
 
		}
	}
 
	......
 
	public static final void main(String[] args) {
		
		.......
 
		ActivityThread thread = new ActivityThread();
		thread.attach(false);
 
		......
 
		Looper.loop();
 
		.......
 
		thread.detach();
		
		......
	}
}

這個函數在進程中創建一個ActivityThread實例,然後調用它的attach函數,接着就進入消息循環了,直到最後進程退出。
函數attach最終調用了ActivityManagerService的遠程接口ActivityManagerProxy的attachApplication函數,傳入的參數是mAppThread,這是一個ApplicationThread類型的Binder對象,它的作用是用來進行進程間通信的。


###Step 25. ActivityManagerProxy.attachApplication

這個函數定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

class ActivityManagerProxy implements IActivityManager
{
	......
 
	public void attachApplication(IApplicationThread app) throws RemoteException
	{
		Parcel data = Parcel.obtain();
		Parcel reply = Parcel.obtain();
		data.writeInterfaceToken(IActivityManager.descriptor);
		data.writeStrongBinder(app.asBinder());
		mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
		reply.readException();
		data.recycle();
		reply.recycle();
	}
 
	......
 
}

這裏通過Binder驅動程序,最後進入ActivityManagerService的attachApplication函數中。


###Step 26. ActivityManagerService.attachApplication

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	public final void attachApplication(IApplicationThread thread) {
		synchronized (this) {
			int callingPid = Binder.getCallingPid();
			final long origId = Binder.clearCallingIdentity();
			attachApplicationLocked(thread, callingPid);
			Binder.restoreCallingIdentity(origId);
		}
	}
 
	......
 
}

這裏將操作轉發給attachApplicationLocked函數。


###Step 27. ActivityManagerService.attachApplicationLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:


public final class ActivityManagerService extends ActivityManagerNative
		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	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);
			}
		} else if (mStartingProcesses.size() > 0) {
			......
		} else {
			......
		}
 
		if (app == null) {
			......
			return false;
		}
 
		......
 
		String processName = app.processName;
		try {
			thread.asBinder().linkToDeath(new AppDeathRecipient(
				app, pid, thread), 0);
		} catch (RemoteException e) {
			......
			return false;
		}
 
		......
 
		app.thread = thread;
		app.curAdj = app.setAdj = -100;
		app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
		app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
		app.forcingToForeground = null;
		app.foregroundServices = false;
		app.debugging = false;
 
		......
 
		boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
 
		......
 
		boolean badApp = false;
		boolean didSomething = false;
 
		// See if the top visible activity is waiting to run in this process...
		ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
		if (hr != null && normalMode) {
			if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
				&& processName.equals(hr.processName)) {
					try {
						if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
							didSomething = true;
						}
					} catch (Exception e) {
						......
					}
			} else {
				......
			}
		}
 
		......
 
		return true;
	}
 
	......
 
}

在前面的Step 23中,已經創建了一個ProcessRecord,這裏首先通過pid將它取回來,放在app變量中,然後對app的其它成員進行初始化,最後調用mMainStack.realStartActivityLocked執行真正的Activity啓動操作。這裏要啓動的Activity通過調用mMainStack.topRunningActivityLocked(null)從堆棧頂端取回來,這時候在堆棧頂端的Activity就是MainActivity了。


###Step 28. ActivityStack.realStartActivityLocked

這個函數定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

public class ActivityStack {
 
	......
 
	final boolean realStartActivityLocked(ActivityRecord r,
			ProcessRecord app, boolean andResume, boolean checkConfig)
			throws RemoteException {
		
		......
 
		r.app = app;
 
		......
 
		int idx = app.activities.indexOf(r);
		if (idx < 0) {
			app.activities.add(r);
		}
		
		......
 
		try {
			......
 
			List<ResultInfo> results = null;
			List<Intent> newIntents = null;
			if (andResume) {
				results = r.results;
				newIntents = r.newIntents;
			}
	
			......
			
			app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
				System.identityHashCode(r),
				r.info, r.icicle, results, newIntents, !andResume,
				mService.isNextTransitionForward());
 
			......
 
		} catch (RemoteException e) {
			......
		}
 
		......
 
		return true;
	}
 
	......
 
}

這裏最終通過app.thread進入到ApplicationThreadProxy的scheduleLaunchActivity函數中,注意,這裏的第二個參數r,是一個ActivityRecord類型的Binder對象,用來作來這個Activity的token值。


###Step 29. ApplicationThreadProxy.scheduleLaunchActivity
這個函數定義在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

class ApplicationThreadProxy implements IApplicationThread {
 
	......
 
	public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
			ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
			List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
			throws RemoteException {
		Parcel data = Parcel.obtain();
		data.writeInterfaceToken(IApplicationThread.descriptor);
		intent.writeToParcel(data, 0);
		data.writeStrongBinder(token);
		data.writeInt(ident);
		info.writeToParcel(data, 0);
		data.writeBundle(state);
		data.writeTypedList(pendingResults);
		data.writeTypedList(pendingNewIntents);
		data.writeInt(notResumed ? 1 : 0);
		data.writeInt(isForward ? 1 : 0);
		mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
			IBinder.FLAG_ONEWAY);
		data.recycle();
	}
 
	......
 

這個函數最終通過Binder驅動程序進入到ApplicationThread的scheduleLaunchActivity函數中。


###Step 30. ApplicationThread.scheduleLaunchActivity
這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
 
	......
 
	private final class ApplicationThread extends ApplicationThreadNative {
 
		......
 
		// 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, Bundle state, List<ResultInfo> pendingResults,
				List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
			ActivityClientRecord r = new ActivityClientRecord();
 
			r.token = token;
			r.ident = ident;
			r.intent = intent;
			r.activityInfo = info;
			r.state = state;
 
			r.pendingResults = pendingResults;
			r.pendingIntents = pendingNewIntents;
 
			r.startsNotResumed = notResumed;
			r.isForward = isForward;
 
			queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
		}
 
		......
 
	}
 
	......
}

函數首先創建一個ActivityClientRecord實例,並且初始化它的成員變量,然後調用ActivityThread類的queueOrSendMessage函數進一步處理。


###Step 31. ActivityThread.queueOrSendMessage

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:


public final class ActivityThread {
 
	......
 
	private final class ApplicationThread extends ApplicationThreadNative {
 
		......
 
		// if the thread hasn't started yet, we don't have the handler, so just
		// save the messages until we're ready.
		private final void queueOrSendMessage(int what, Object obj) {
			queueOrSendMessage(what, obj, 0, 0);
		}
 
		......
 
		private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
			synchronized (this) {
				......
				Message msg = Message.obtain();
				msg.what = what;
				msg.obj = obj;
				msg.arg1 = arg1;
				msg.arg2 = arg2;
				mH.sendMessage(msg);
			}
		}
 
		......
 
	}
 
	......
}

函數把消息內容放在msg中,然後通過mH把消息分發出去,這裏的成員變量mH我們在前面已經見過,消息分發出去後,最後會調用H類的handleMessage函數。


###Step 32. H.handleMessage

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:


public final class ActivityThread {
 
	......
 
	private final class H extends Handler {
 
		......
 
		public void handleMessage(Message msg) {
			......
			switch (msg.what) {
			case LAUNCH_ACTIVITY: {
				ActivityClientRecord r = (ActivityClientRecord)msg.obj;
 
				r.packageInfo = getPackageInfoNoCheck(
					r.activityInfo.applicationInfo);
				handleLaunchActivity(r, null);
			} break;
			......
			}
 
		......
 
	}
 
	......
}

這裏最後調用ActivityThread類的handleLaunchActivity函數進一步處理。


###Step 33. ActivityThread.handleLaunchActivity

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
 
	......
 
	private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		......
 
		Activity a = performLaunchActivity(r, customIntent);
 
		if (a != null) {
			r.createdConfig = new Configuration(mConfiguration);
			Bundle oldState = r.state;
			handleResumeActivity(r.token, false, r.isForward);
 
			......
		} else {
			......
		}
	}
 
	......
}

這裏首先調用performLaunchActivity函數來加載這個Activity類,即shy.luo.activity.MainActivity,然後調用它的onCreate函數,最後回到handleLaunchActivity函數時,再調用handleResumeActivity函數來使這個Activity進入Resumed狀態,即會調用這個Activity的onResume函數,這是遵循Activity的生命週期的。


###Step 34. ActivityThread.performLaunchActivity

這個函數定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
 
	......
 
	private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		
		ActivityInfo aInfo = r.activityInfo;
		if (r.packageInfo == null) {
			r.packageInfo = getPackageInfo(aInfo.applicationInfo,
				Context.CONTEXT_INCLUDE_CODE);
		}
 
		ComponentName component = r.intent.getComponent();
		if (component == null) {
			component = r.intent.resolveActivity(
				mInitialApplication.getPackageManager());
			r.intent.setComponent(component);
		}
 
		if (r.activityInfo.targetActivity != null) {
			component = new ComponentName(r.activityInfo.packageName,
				r.activityInfo.targetActivity);
		}
 
		Activity activity = null;
		try {
			java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
			activity = mInstrumentation.newActivity(
				cl, component.getClassName(), r.intent);
			r.intent.setExtrasClassLoader(cl);
			if (r.state != null) {
				r.state.setClassLoader(cl);
			}
		} catch (Exception e) {
			......
		}
 
		try {
			Application app = r.packageInfo.makeApplication(false, mInstrumentation);
 
			......
 
			if (activity != null) {
				ContextImpl appContext = new ContextImpl();
				appContext.init(r.packageInfo, r.token, this);
				appContext.setOuterContext(activity);
				CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
				Configuration config = new Configuration(mConfiguration);
				......
				activity.attach(appContext, this, getInstrumentation(), r.token,
					r.ident, app, r.intent, r.activityInfo, title, r.parent,
					r.embeddedID, r.lastNonConfigurationInstance,
					r.lastNonConfigurationChildInstances, config);
 
				if (customIntent != null) {
					activity.mIntent = customIntent;
				}
				r.lastNonConfigurationInstance = null;
				r.lastNonConfigurationChildInstances = null;
				activity.mStartedActivity = false;
				int theme = r.activityInfo.getThemeResource();
				if (theme != 0) {
					activity.setTheme(theme);
				}
 
				activity.mCalled = false;
				mInstrumentation.callActivityOnCreate(activity, r.state);
				......
				r.activity = activity;
				r.stopped = true;
				if (!r.activity.mFinished) {
					activity.performStart();
					r.stopped = false;
				}
				if (!r.activity.mFinished) {
					if (r.state != null) {
						mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
					}
				}
				if (!r.activity.mFinished) {
					activity.mCalled = false;
					mInstrumentation.callActivityOnPostCreate(activity, r.state);
					if (!activity.mCalled) {
						throw new SuperNotCalledException(
							"Activity " + r.intent.getComponent().toShortString() +
							" did not call through to super.onPostCreate()");
					}
				}
			}
			r.paused = true;
 
			mActivities.put(r.token, r);
 
		} catch (SuperNotCalledException e) {
			......
 
		} catch (Exception e) {
			......
		}
 
		return activity;
	}
 
	......
}

函數前面是收集要啓動的Activity的相關信息,主要package和component信息:


   ActivityInfo aInfo = r.activityInfo;
   if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo,
                Context.CONTEXT_INCLUDE_CODE);
   }
 
   ComponentName component = r.intent.getComponent();
   if (component == null) {
       component = r.intent.resolveActivity(
           mInitialApplication.getPackageManager());
       r.intent.setComponent(component);
   }
 
   if (r.activityInfo.targetActivity != null) {
       component = new ComponentName(r.activityInfo.packageName,
               r.activityInfo.targetActivity);
   }

然後通過ClassLoader將shy.luo.activity.MainActivity類加載進來:

   Activity activity = null;
   try {
	java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
	activity = mInstrumentation.newActivity(
		cl, component.getClassName(), r.intent);
	r.intent.setExtrasClassLoader(cl);
	if (r.state != null) {
		r.state.setClassLoader(cl);
	}
   } catch (Exception e) {
	......
   }

接下來是創建Application對象,這是根據AndroidManifest.xml配置文件中的Application標籤的信息來創建的:

 Application app = r.packageInfo.makeApplication(false, mInstrumentation);

後面的代碼主要創建Activity的上下文信息,並通過attach方法將這些上下文信息設置到MainActivity中去:

   activity.attach(appContext, this, getInstrumentation(), r.token,
	r.ident, app, r.intent, r.activityInfo, title, r.parent,
	r.embeddedID, r.lastNonConfigurationInstance,
	r.lastNonConfigurationChildInstances, config);

最後還要調用MainActivity的onCreate函數:

   mInstrumentation.callActivityOnCreate(activity, r.state);

這裏不是直接調用MainActivity的onCreate函數,而是通過mInstrumentation的callActivityOnCreate函數來間接調用,前面我們說過,mInstrumentation在這裏的作用是監控Activity與系統的交互操作,相當於是系統運行日誌。


###Step 35. MainActivity.onCreate

這個函數定義在packages/experimental/Activity/src/shy/luo/activity/MainActivity.java文件中,這是我們自定義的app工程文件:

public class MainActivity extends Activity  implements OnClickListener {
	
	......
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		......
 
		Log.i(LOG_TAG, "Main Activity Created.");
	}
 
	......
 
}

這樣,MainActivity就啓動起來了,整個應用程序也啓動起來了。


總結

整個應用程序的啓動過程要執行很多步驟,但是整體來看,主要分爲以下五個階段:

  • 一. Step1 - Step 11:Launcher通過Binder進程間通信機制通知ActivityManagerService,它要啓動一個Activity;

  • 二. Step 12 - Step 16:ActivityManagerService通過Binder進程間通信機制通知Launcher進入Paused狀態;

  • 三. Step 17 - Step 24:Launcher通過Binder進程間通信機制通知ActivityManagerService,它已經準備就緒進入Paused狀態,於是ActivityManagerService就創建一個新的進程,用來啓動一個ActivityThread實例,即將要啓動的Activity就是在這個ActivityThread實例中運行;

  • 四. Step 25 - Step 27:ActivityThread通過Binder進程間通信機制將一個ApplicationThread類型的Binder對象傳遞給ActivityManagerService,以便以後ActivityManagerService能夠通過這個Binder對象和它進行通信;

  • 五. Step 28 - Step 35:ActivityManagerService通過Binder進程間通信機制通知ActivityThread,現在一切準備就緒,它可以真正執行Activity的啓動操作了。

發佈了82 篇原創文章 · 獲贊 215 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章