2、詳細分析 對于一個開發者來說啟動一個Activity使用Intent來實現的,如下代碼很常見:
Intent intent=new Intent(this,cls);
startActivity(intent);
是的,我們只需要調用startActivity方法就可以實現了,那么這個startActivity是怎么樣的呢?一個Activity的啟動又經歷那些呢? (1)startActivity和startActivityForResult方法 startActivity方法是Activity.Java里面的方法,而且這個方法有很多重載形式,但是無論哪種形式的startActivity方法最終都調用了startActivityForResult方法。
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
}
if (requestCode >= 0)
{
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the // activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because // that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
}
//代碼省略
}
很顯然,在這段代碼中有一個判斷是if (mParent == null) ,那么這個mParent是個什么東西呢?如果你去探索你會發現mParent是一個ActivityGroup,這個東西早在Android3.0的時候就被Fragment所取代,那么這里也就不再對其做討論。在這個if中第一個部分是這段代碼:
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(),
mToken, this, intent, requestCode, options);
我們看到變量 Instrumentation調用了一個叫execStartActivity的方法,出于程序員的直覺,我感覺這就是啟動Activity的方法,這個方法有7個參數,這里我無法一個一個去分析。但是mMainThread.getApplication()一定會引起你的注意,mMainThread是什么呢?她是一個ActivityThread實例,而這個ActivityThread就是我們通常所說的UI線程或者說主線程,getApplicationThread方法那到底是ApplicationThread實例,這個ApplicationThread類是ActivityThread的內部類。后經分析發現ApplicationThread在Activity的啟動過程中發揮了很重要的作用。最后我們打開execStartActivity方法 (2)Instrumenation中的execStartActivity方法 準確的來說execStartActivity方法是ActivityResult類中的方法,但是ActivityResult類是Instrumentation的內部類,同樣還是來看下execStartActivity的具體實現:
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options)
{
//代碼省略
try {
intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e)
{
throw new RuntimeException("Failure from system", e);
}
return null;
}
大致閱讀了一下代碼,發現一段十分引人注目的代碼
int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(),
intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
這里又出現了叫startActivity的方法,那么兄弟們這個意思還不夠明顯嗎?這里你會看到startActivity返回的是一個int類型的結果,而這個返回值我們可以將其理解為Activity的啟動結果,隨后這個返回值result做為checkStartActivityResult方法的參數。checkStartActivityResult方法時干嘛用的呢?從名字不難看出這個方法是用來檢查Activity的啟動結果的。打開checkStartActivityResult方法一探究竟,代碼如下:
/** @hide */ public static void checkStartActivityResult(int res, Object intent) {
if (res >= ActivityManager.START_SUCCESS)
{
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException( "Unable to find explicit activity class " + ((Intent)intent).getComponent().toShortString() + "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException( "No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity " + intent);
case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
throw new AndroidRuntimeException( "FORWARD_RESULT_FLAG used while also requesting a result"); case ActivityManager.START_NOT_ACTIVITY: throw new IllegalArgumentException( "PendingIntent is not an activity"); case ActivityManager.START_NOT_VOICE_COMPATIBLE: throw new SecurityException( "Starting under voice control not allowed for: " + intent);
case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
// Fail silently for this case so we don't break current apps. // TODO(b/22929608): Instead of failing silently or throwing an exception,
// we should properly position the activity in the stack (i.e. behind all current // user activity/task) and not change the positioning of stacks. Log.e(TAG, "Not allowed to start background user activity that shouldn't be displayed" + " for all users. Failing silently...");
break;
default:
throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent);
}
}
果不其然這個方法就是用來檢查Activity的啟動結果的,代碼分為兩個部分,第一是if部分,第二switch部分
A if部分代碼 這部分代碼很簡單,意思就是說當Activity的啟動結果等于或大于ActivityManager.START_SUCCESS的時候Activity啟動成功!
if (res >= ActivityManager.START_SUCCESS) { return; }
B switch部分代碼 switch部分代碼給出了啟動不成功的n中形式,并拋出異常,細心的我們發現。常見的錯誤“have you declared this activity in your AndroidManifest.xml?”就是這里拋出的。到此checkStartActivityResult方法分析結束。 但是還有一個疑問我們沒有解決!那就是ActivityManagerNative到底是個什么呢?看到《Android開發藝術探索》一書中寫到“ActivityManagerNative就是一個AMS”,好吧!概括的很直接,但是我總覺得如果我也就這么直接的告訴你,顯然不夠意思。那么我們打開ActivityManagerNative看看它到底是什么吧!
public abstract class ActivityManagerNative extends Binder implements IActivityManager
可以看到ActivityManagerNative是一個Binder并且實現了IActivityManager接口,那么為什么《Android開發藝術探索》作者會說ActivityManagerNative.getDefault()是一個AMS呢?為了搞明白這個我們來看下getDefault()方法
/** * Retrieve the system's default/global activity manager. */ static public IActivityManager getDefault() { return gDefault.get(); }
這個方法的返回類型可以看出ActivityManagerNative.getDefault()返回的是一個IActivityManager,那么事實是不是這樣的呢?我們找到gDefault創建的地方
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) { Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
看到gDefault是一個Singleton,打開Singleton類:
package android.util;/** * Singleton helper class for lazily initialization. * * Modeled after frameworks/base/include/utils/Singleton.h * * @hide */public abstract class Singleton<T> { private T mInstance; protected abstract T create(); public final T get() { synchronized (this) { if (mInstance == null) { mInstance = create(); } return mInstance; } }}
Singleton類中有兩個方法,create()和get(),他們的返回類型都是T,并且create方法是一個抽象方法,所以create方法必須被重寫,仔細觀察可以發現get方法中有mInstance = create();這行代碼,綜合上推斷gDefault.getDefault()就是一個IActivityManager實例,而這個實例調用了asInterface方法。我們接著來看下asInterface方法:
/** * Cast a Binder object into an activity manager interface, generating * a proxy if needed. */ static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj); }
而asInterface最終返回的是一個ActivityManagerProxy實例。也就是說經過這么長時間的推斷,基本可以得出結論ActivityManagerNative.getDefault()是一個ActivityManagerProxy,而ActivityManagerProxy則是AMS的代理,所以說ActivityManagerNative.getDefault()是一個AMS并不為過。到此,我們總算是可以接著往下走了。
(3)AMS中的startActivity方法以及startActivityasUser方法 先來看下AMS中的startActivity方法,代碼如下:
@Override public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId()); }
這里沒什么好說的再看下startActivityAsUser方法
@Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { enforceNotIsolatedCaller("startActivity"); userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: Switch to user app stacks here. return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, userId, null, null); }
毫無疑問我們的下一站便是startActivityMayWait,只是我們要確定的是mStackSupervisor是什么。 (4)ActivityStackSupervisor中的一系列方法
final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration config, Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) { //代碼省略 int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, componentSpecified, null, container, inTask); //代碼省略 return res; } }
到了這里筆者就有很多代碼是看不懂的了畢竟能力有限,不過沒有關系,我們可以通過看該方法返回的東西還尋找線索。我們看到return res;那么這個res是怎么來的呢,繼續尋找發現了這樣一段代碼:
int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, componentSpecified, null, container, inTask);
好了這就算是找到了。 那么接下來我們看下這個startActivityLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {//代碼省略 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); mStackSupervisor.startSpecificActivityLocked(next, true, true); } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true;}
查找一番,我們發現在resumeTopActivityInnerLocked方法中調用了startSpecificActivityLocked方法。 (6)又回到ActivityStackSupervisor startSpecificActivityLocked方法是ActivityStackSupervisor中的一個方法,沒錯兄弟們我們又回來了。繼續深入研究我們打開startSpecificActivityLocked方法:
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);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"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, r.info.applicationInfo.versionCode, 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);
}
一樣過濾掉無用的代碼,我們的目光鎖定在if條件下的代碼塊中,我們發現系統緊接著有調用了realStartActivityLocked方法,繼續往下走打開realStartActivityLocked方法:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { //代碼省略 ProfilerInfo profilerInfo = profileFile != null ? new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval, mService.mAutoStopProfiler) : null; app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); //代碼省略 return true; }
這段代碼依舊很長,不過我們始終要記得我們要研究的是什么,所以很多代碼不用理會。很快我們找到了這段代碼:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
很顯然Activity的啟動有轉移到了scheduleLaunchActivity方法中了,不過在打開scheduleLaunchActivity之前我們先要搞明白app.thread是什么。點進去一看發現app.thread是一個IApplicationThread,打開IApplicationThread代碼如下:
package android.app;
//代碼省略
/** *
System private API for communicating with the application. This is given to * the activity manager by an application when it starts up, for the activity * manager to tell the application about things it needs to do. * * {@hide} */
public interface IApplicationThread extends IInterface {
void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) throws RemoteException; void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException; void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs) throws RemoteException;
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException;
void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig) throws RemoteException;
void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException;
void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException;
void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) throws RemoteException;
static final int BACKUP_MODE_INCREMENTAL = 0;
static final int BACKUP_MODE_FULL = 1;
static final int BACKUP_MODE_RESTORE = 2;
static final int BACKUP_MODE_RESTORE_FULL = 3;
void scheduleCreateBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo, int backupMode) throws RemoteException;
void scheduleDestroyBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo) throws RemoteException;
void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) throws RemoteException;
void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) throws RemoteException;
void scheduleUnbindService(IBinder token, Intent intent) throws RemoteException;
void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, int flags, Intent args) throws RemoteException;
void scheduleStopService(IBinder token) throws RemoteException;
static final int DEBUG_OFF = 0;
static final int DEBUG_ON = 1;
static final int DEBUG_WAIT = 2;
void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments, IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection, int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) throws RemoteException;
void scheduleExit() throws RemoteException; void scheduleSuicide() throws RemoteException;
void scheduleConfigurationChanged(Configuration config) throws RemoteException;
void updateTimeZone() throws RemoteException; void clearDnsCache() throws RemoteException;
void setHttpProxy(String proxy, String port, String exclList, Uri pacFileUrl) throws RemoteException;
void processInBackground() throws RemoteException;
void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) throws RemoteException;
void dumpProvider(FileDescriptor fd, IBinder servicetoken, String[] args) throws RemoteException;
void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser, int processState) throws RemoteException;
void scheduleLowMemory() throws RemoteException;
void scheduleActivityConfigurationChanged(IBinder token, Configuration overrideConfig) throws RemoteException; void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) throws RemoteException; void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) throws RemoteException; void setSchedulingGroup(int group) throws RemoteException; static final int PACKAGE_REMOVED = 0; static final int EXTERNAL_STORAGE_UNAVAILABLE = 1; void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException; void scheduleCrash(String msg) throws RemoteException;
void dumpActivity(FileDescriptor fd, IBinder servicetoken, String prefix, String[] args) throws RemoteException;
void setCoreSettings(Bundle coreSettings) throws RemoteException;
void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
void scheduleTrimMemory(int level) throws RemoteException;
void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) throws RemoteException;
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
void unstableProviderDied(IBinder provider) throws RemoteException; void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType) throws RemoteException;
void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) throws RemoteException;
void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) throws RemoteException;
void setProcessState(int state) throws RemoteException; void scheduleInstallProvider(ProviderInfo provider) throws RemoteException; void updateTimePrefs(boolean is24Hour) throws RemoteException;
void scheduleCancelVisibleBehind(IBinder token) throws RemoteException;
void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException;
void scheduleEnterAnimationComplete(IBinder token) throws RemoteException;
void notifyCleartextNetwork(byte[] firstPacket) throws RemoteException; String descriptor = "android.app.IApplicationThread";
int SCHEDULE_PAUSE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
int SCHEDULE_STOP_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
int SCHEDULE_WINDOW_VISIBILITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
int SCHEDULE_RESUME_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
int SCHEDULE_SEND_RESULT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
int SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+6;
int SCHEDULE_NEW_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+7;
int SCHEDULE_FINISH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+8;
int SCHEDULE_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+9;
int SCHEDULE_CREATE_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+10;
int SCHEDULE_STOP_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+11;
int BIND_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+12;
int SCHEDULE_EXIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+13;
int SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+15;
int SCHEDULE_SERVICE_ARGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+16;
int UPDATE_TIME_ZONE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+17;
int PROCESS_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+18;
int SCHEDULE_BIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+19;
int SCHEDULE_UNBIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+20;
int DUMP_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+21;
int SCHEDULE_REGISTERED_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+22;
int SCHEDULE_LOW_MEMORY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+23;
int SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+24;
int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
int SCHEDULE_SLEEPING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29; int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30; int SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
int DISPATCH_PACKAGE_BROADCAST_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
int SCHEDULE_CRASH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+34;
int DUMP_HEAP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+35;
int DUMP_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+36;
int CLEAR_DNS_CACHE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+37;
int SET_HTTP_PROXY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+38;
int SET_CORE_SETTINGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+39;
int UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+40;
int SCHEDULE_TRIM_MEMORY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+41;
int DUMP_MEM_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+42;
int DUMP_GFX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+43;
int DUMP_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47; int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
int UPDATE_TIME_PREFS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51;
int CANCEL_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52;
int BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53;
int ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54;
int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+55;
}
IApplicationThread繼承了IInterface這說明它是一個Binder接口,其中定義為了很多方法包括了scheduleLaunchActivity方法。既然IApplicationThread是一個接口,那么他必須要有實現者,這樣才能繼續走下去。查閱資料發現IApplicationThread的實現者就是ApplicationThread,那么我們明白了到了這Activity的啟動過程已經進入了主線程。
(7)ApplicationThread中的scheduLaunchActivity方法 前面說過ApplicationThread是ActivityThread的內部類,回到ActivityThread去找ApplicationThread的身影:
private class ApplicationThread extends ApplicationThreadNative {
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
private int mLastProcessState = -1;
//代碼省略
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo)
{
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token; r.ident = ident; r.intent = intent;
r.referrer = referrer; r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
//代碼省略
}
ApplicationThread繼承了ApplicationThreadNative類,但是好像沒有實現IApplicationThread接口,是不是前面的說發錯了?先別急,我們來看看ApplicationThreadNative:
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
原來如此,ApplicationThreadNative 實現了IApplicationThread,與此同時ApplicationThreadNative是一個抽象的類,所以說ApplicationThread實現了IApplicationThread說法沒有問題。ApplicationThread中實現了IApplicationThread中的方法,幾乎每種方法都是用sendMessage方法發送消息,包括scheduleLaunchActivity方法。說到sendMessage是不是很容易想起Handler?
(8)一個叫H的handler 順著這個思路,我們找到了一個叫H的handler,哈!Google的工程師真懶!這個Handler就是用來處理消息的,既然有sendMessage那就必然有handleMessage方法用于處理消息。我們找到處理scheduleLaunchActivity方法發送的消息的代碼塊:
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break;
我們發現handleLaunchActivity方法被調用它,進而找到該方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. //代碼省略 Activity a = performLaunchActivity(r, customIntent); //代碼省略}
令人欣喜的是我們終于看到Activity的實例了,并且應該是由performLaunchActivity方法創建的,為了證實這個觀點我們再去看看performLaunchActivity方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 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); StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null)
{
r.state.setClassLoader(cl);
}
}
catch (Exception e) {
if (!mInstrumentation.onException(activity, e))
{
throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e);
}
}
try { Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v( TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor);
if (customIntent != null)
{
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
}
else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()");
}
r.activity = activity; r.stopped = true;
if (!r.activity.mFinished)
{
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState);
}
}
else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState);
} else {
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) {
throw e;
}
catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException( "Unable to start activity " + component + ": " + e.toString(), e);
}
}
return activity;
}
performLaunchActivity方法中所做的事情比較多,下面我們來簡單的說一下。第一從ActivityClientRecord中獲取待啟動的Activity的信息,第二通過Instrumentation的newActivity方法來創建Activity的對象,第三通過LoadedApk的makeApplication方法來穿件Application對象,第四創建ContextImpl對象并通過Activity的attch方法來完成一下數據的初始化,第五調用onCreate方法
不得不說這真是一個漫長的過程,在一個簡單的操作背后竟然有如此多的故事,作為一個Android開發者Android就想一片汪洋等待著我們去探索,為此我將不斷努力。
參考書籍 《Android開發藝術探索》
參考文章 http://blog.csdn.net/xyh269/article/details/52752018
原文鏈接 http://blog.csdn.net/grrlc1314/article/details/53988705