詳解Activity的啟動(dòng)過(guò)程

一直以來(lái)對(duì)于Activity的啟動(dòng)過(guò)程讓我充滿好奇,廢話不多說(shuō)我們直接開(kāi)始吧 1脉漏、Activity啟動(dòng)圖解
這里寫(xiě)圖片描述

2、詳細(xì)分析 對(duì)于一個(gè)開(kāi)發(fā)者來(lái)說(shuō)啟動(dòng)一個(gè)Activity使用Intent來(lái)實(shí)現(xiàn)的,如下代碼很常見(jiàn):

Intent intent=new Intent(this,cls);
startActivity(intent);

是的手形,我們只需要調(diào)用startActivity方法就可以實(shí)現(xiàn)了,那么這個(gè)startActivity是怎么樣的呢悯恍?一個(gè)Activity的啟動(dòng)又經(jīng)歷那些呢库糠? (1)startActivity和startActivityForResult方法 startActivity方法是Activity.Java里面的方法,而且這個(gè)方法有很多重載形式涮毫,但是無(wú)論哪種形式的startActivity方法最終都調(diào)用了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. 
} 
//代碼省略 
}

很顯然,在這段代碼中有一個(gè)判斷是if (mParent == null) ,那么這個(gè)mParent是個(gè)什么東西呢窒百?如果你去探索你會(huì)發(fā)現(xiàn)mParent是一個(gè)ActivityGroup黍判,這個(gè)東西早在Android3.0的時(shí)候就被Fragment所取代,那么這里也就不再對(duì)其做討論篙梢。在這個(gè)if中第一個(gè)部分是這段代碼:

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), 
mToken, this, intent, requestCode, options);

我們看到變量 Instrumentation調(diào)用了一個(gè)叫execStartActivity的方法顷帖,出于程序員的直覺(jué),我感覺(jué)這就是啟動(dòng)Activity的方法渤滞,這個(gè)方法有7個(gè)參數(shù)贬墩,這里我無(wú)法一個(gè)一個(gè)去分析。但是mMainThread.getApplication()一定會(huì)引起你的注意妄呕,mMainThread是什么呢陶舞?她是一個(gè)ActivityThread實(shí)例,而這個(gè)ActivityThread就是我們通常所說(shuō)的UI線程或者說(shuō)主線程绪励,getApplicationThread方法那到底是ApplicationThread實(shí)例肿孵,這個(gè)ApplicationThread類(lèi)是ActivityThread的內(nèi)部類(lèi)。后經(jīng)分析發(fā)現(xiàn)ApplicationThread在Activity的啟動(dòng)過(guò)程中發(fā)揮了很重要的作用疏魏。最后我們打開(kāi)execStartActivity方法 (2)Instrumenation中的execStartActivity方法 準(zhǔn)確的來(lái)說(shuō)execStartActivity方法是ActivityResult類(lèi)中的方法停做,但是ActivityResult類(lèi)是Instrumentation的內(nèi)部類(lèi),同樣還是來(lái)看下execStartActivity的具體實(shí)現(xiàn):

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;
 }

大致閱讀了一下代碼大莫,發(fā)現(xiàn)一段十分引人注目的代碼

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);

這里又出現(xiàn)了叫startActivity的方法蛉腌,那么兄弟們這個(gè)意思還不夠明顯嗎?這里你會(huì)看到startActivity返回的是一個(gè)int類(lèi)型的結(jié)果,而這個(gè)返回值我們可以將其理解為Activity的啟動(dòng)結(jié)果烙丛,隨后這個(gè)返回值result做為checkStartActivityResult方法的參數(shù)舅巷。checkStartActivityResult方法時(shí)干嘛用的呢?從名字不難看出這個(gè)方法是用來(lái)檢查Activity的啟動(dòng)結(jié)果的河咽。打開(kāi)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); 
} 
}

果不其然這個(gè)方法就是用來(lái)檢查Activity的啟動(dòng)結(jié)果的,代碼分為兩個(gè)部分库北,第一是if部分爬舰,第二switch部分
A if部分代碼 這部分代碼很簡(jiǎn)單,意思就是說(shuō)當(dāng)Activity的啟動(dòng)結(jié)果等于或大于ActivityManager.START_SUCCESS的時(shí)候Activity啟動(dòng)成功寒瓦!

if (res >= ActivityManager.START_SUCCESS) { return; }

B switch部分代碼 switch部分代碼給出了啟動(dòng)不成功的n中形式情屹,并拋出異常,細(xì)心的我們發(fā)現(xiàn)杂腰。常見(jiàn)的錯(cuò)誤“have you declared this activity in your AndroidManifest.xml?”就是這里拋出的垃你。到此checkStartActivityResult方法分析結(jié)束。 但是還有一個(gè)疑問(wèn)我們沒(méi)有解決喂很!那就是ActivityManagerNative到底是個(gè)什么呢惜颇?看到《Android開(kāi)發(fā)藝術(shù)探索》一書(shū)中寫(xiě)到“ActivityManagerNative就是一個(gè)AMS”,好吧少辣!概括的很直接凌摄,但是我總覺(jué)得如果我也就這么直接的告訴你,顯然不夠意思漓帅。那么我們打開(kāi)ActivityManagerNative看看它到底是什么吧锨亏!

public abstract class ActivityManagerNative extends Binder implements IActivityManager

可以看到ActivityManagerNative是一個(gè)Binder并且實(shí)現(xiàn)了IActivityManager接口,那么為什么《Android開(kāi)發(fā)藝術(shù)探索》作者會(huì)說(shuō)ActivityManagerNative.getDefault()是一個(gè)AMS呢忙干?為了搞明白這個(gè)我們來(lái)看下getDefault()方法

/** * Retrieve the system's default/global activity manager. */ static public IActivityManager getDefault() { return gDefault.get(); }

這個(gè)方法的返回類(lèi)型可以看出ActivityManagerNative.getDefault()返回的是一個(gè)IActivityManager器予,那么事實(shí)是不是這樣的呢?我們找到gDefault創(chuàng)建的地方

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是一個(gè)Singleton捐迫,打開(kāi)Singleton類(lèi):

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類(lèi)中有兩個(gè)方法乾翔,create()和get(),他們的返回類(lèi)型都是T施戴,并且create方法是一個(gè)抽象方法反浓,所以create方法必須被重寫(xiě),仔細(xì)觀察可以發(fā)現(xiàn)get方法中有mInstance = create();這行代碼赞哗,綜合上推斷gDefault.getDefault()就是一個(gè)IActivityManager實(shí)例勾习,而這個(gè)實(shí)例調(diào)用了asInterface方法。我們接著來(lái)看下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最終返回的是一個(gè)ActivityManagerProxy實(shí)例懈玻。也就是說(shuō)經(jīng)過(guò)這么長(zhǎng)時(shí)間的推斷,基本可以得出結(jié)論ActivityManagerNative.getDefault()是一個(gè)ActivityManagerProxy,而ActivityManagerProxy則是AMS的代理涂乌,所以說(shuō)ActivityManagerNative.getDefault()是一個(gè)AMS并不為過(guò)艺栈。到此,我們總算是可以接著往下走了湾盒。

(3)AMS中的startActivity方法以及startActivityasUser方法 先來(lái)看下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()); }

這里沒(méi)什么好說(shuō)的再看下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); }

毫無(wú)疑問(wèn)我們的下一站便是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; } }

到了這里筆者就有很多代碼是看不懂的了畢竟能力有限毅人,不過(guò)沒(méi)有關(guān)系,我們可以通過(guò)看該方法返回的東西還尋找線索尖殃。我們看到return res丈莺;那么這個(gè)res是怎么來(lái)的呢,繼續(xù)尋找發(fā)現(xiàn)了這樣一段代碼:

int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, componentSpecified, null, container, inTask);

好了這就算是找到了送丰。 那么接下來(lái)我們看下這個(gè)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;}

查找一番缔俄,我們發(fā)現(xiàn)在resumeTopActivityInnerLocked方法中調(diào)用了startSpecificActivityLocked方法。 (6)又回到ActivityStackSupervisor startSpecificActivityLocked方法是ActivityStackSupervisor中的一個(gè)方法器躏,沒(méi)錯(cuò)兄弟們我們又回來(lái)了俐载。繼續(xù)深入研究我們打開(kāi)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); 
}

一樣過(guò)濾掉無(wú)用的代碼,我們的目光鎖定在if條件下的代碼塊中登失,我們發(fā)現(xiàn)系統(tǒng)緊接著有調(diào)用了realStartActivityLocked方法遏佣,繼續(xù)往下走打開(kāi)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; }

這段代碼依舊很長(zhǎng),不過(guò)我們始終要記得我們要研究的是什么揽浙,所以很多代碼不用理會(huì)状婶。很快我們找到了這段代碼:

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的啟動(dòng)有轉(zhuǎn)移到了scheduleLaunchActivity方法中了,不過(guò)在打開(kāi)scheduleLaunchActivity之前我們先要搞明白app.thread是什么捏萍。點(diǎn)進(jìn)去一看發(fā)現(xiàn)app.thread是一個(gè)IApplicationThread太抓,打開(kāi)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這說(shuō)明它是一個(gè)Binder接口,其中定義為了很多方法包括了scheduleLaunchActivity方法令杈。既然IApplicationThread是一個(gè)接口走敌,那么他必須要有實(shí)現(xiàn)者,這樣才能繼續(xù)走下去逗噩。查閱資料發(fā)現(xiàn)IApplicationThread的實(shí)現(xiàn)者就是ApplicationThread掉丽,那么我們明白了到了這Activity的啟動(dòng)過(guò)程已經(jīng)進(jìn)入了主線程。
(7)ApplicationThread中的scheduLaunchActivity方法 前面說(shuō)過(guò)ApplicationThread是ActivityThread的內(nèi)部類(lèi)异雁,回到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類(lèi)捶障,但是好像沒(méi)有實(shí)現(xiàn)IApplicationThread接口,是不是前面的說(shuō)發(fā)錯(cuò)了纲刀?先別急项炼,我們來(lái)看看ApplicationThreadNative:

public abstract class ApplicationThreadNative extends Binder implements IApplicationThread 

原來(lái)如此,ApplicationThreadNative 實(shí)現(xiàn)了IApplicationThread,與此同時(shí)ApplicationThreadNative是一個(gè)抽象的類(lèi)锭部,所以說(shuō)ApplicationThread實(shí)現(xiàn)了IApplicationThread說(shuō)法沒(méi)有問(wèn)題暂论。ApplicationThread中實(shí)現(xiàn)了IApplicationThread中的方法,幾乎每種方法都是用sendMessage方法發(fā)送消息拌禾,包括scheduleLaunchActivity方法取胎。說(shuō)到sendMessage是不是很容易想起Handler?
(8)一個(gè)叫H的handler 順著這個(gè)思路湃窍,我們找到了一個(gè)叫H的handler闻蛀,哈!Google的工程師真懶您市!這個(gè)Handler就是用來(lái)處理消息的觉痛,既然有sendMessage那就必然有handleMessage方法用于處理消息。我們找到處理scheduleLaunchActivity方法發(fā)送的消息的代碼塊:

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;

我們發(fā)現(xiàn)handleLaunchActivity方法被調(diào)用它墨坚,進(jìn)而找到該方法:

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的實(shí)例了秧饮,并且應(yīng)該是由performLaunchActivity方法創(chuàng)建的,為了證實(shí)這個(gè)觀點(diǎn)我們?cè)偃タ纯磒erformLaunchActivity方法:

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方法中所做的事情比較多泽篮,下面我們來(lái)簡(jiǎn)單的說(shuō)一下盗尸。第一從ActivityClientRecord中獲取待啟動(dòng)的Activity的信息,第二通過(guò)Instrumentation的newActivity方法來(lái)創(chuàng)建Activity的對(duì)象帽撑,第三通過(guò)LoadedApk的makeApplication方法來(lái)穿件Application對(duì)象泼各,第四創(chuàng)建ContextImpl對(duì)象并通過(guò)Activity的attch方法來(lái)完成一下數(shù)據(jù)的初始化,第五調(diào)用onCreate方法
不得不說(shuō)這真是一個(gè)漫長(zhǎng)的過(guò)程亏拉,在一個(gè)簡(jiǎn)單的操作背后竟然有如此多的故事扣蜻,作為一個(gè)Android開(kāi)發(fā)者Android就想一片汪洋等待著我們?nèi)ヌ剿鳎瑸榇宋覍⒉粩嗯Α?br> 參考書(shū)籍 《Android開(kāi)發(fā)藝術(shù)探索》
參考文章 http://blog.csdn.net/xyh269/article/details/52752018
原文鏈接 http://blog.csdn.net/grrlc1314/article/details/53988705

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末及塘,一起剝皮案震驚了整個(gè)濱河市莽使,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笙僚,老刑警劉巖芳肌,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肋层,居然都是意外死亡亿笤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)栋猖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)净薛,“玉大人,你說(shuō)我怎么就攤上這事蒲拉∷喟荩” “怎么了痴腌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)爆班。 經(jīng)常有香客問(wèn)我衷掷,道長(zhǎng),這世上最難降的妖魔是什么柿菩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮雨涛,結(jié)果婚禮上枢舶,老公的妹妹穿的比我還像新娘。我一直安慰自己替久,他們只是感情好凉泄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蚯根,像睡著了一般后众。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颅拦,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天蒂誉,我揣著相機(jī)與錄音,去河邊找鬼距帅。 笑死右锨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碌秸。 我是一名探鬼主播绍移,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼讥电!你這毒婦竟也來(lái)了蹂窖?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恩敌,失蹤者是張志新(化名)和其女友劉穎瞬测,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體潮剪,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涣楷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抗碰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狮斗。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弧蝇,靈堂內(nèi)的尸體忽然破棺而出碳褒,到底是詐尸還是另有隱情折砸,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布沙峻,位于F島的核電站睦授,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏摔寨。R本人自食惡果不足惜去枷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望是复。 院中可真熱鬧删顶,春花似錦、人聲如沸淑廊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)季惩。三九已至录粱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間画拾,已是汗流浹背啥繁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碾阁,地道東北人输虱。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像脂凶,于是被迫代替她去往敵國(guó)和親宪睹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容