详解Activity的启动过程

作者: grr1314 | 来源:发表于2017-01-03 15:01 被阅读617次
    一直以来对于Activity的启动过程让我充满好奇,废话不多说我们直接开始吧 1、Activity启动图解 这里写图片描述

    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

    相关文章

      网友评论

      • super_shanks:可以麻烦解释一下:
        case ActivityManager.START_PERMISSION_DENIED:
        throw new SecurityException("Not allowed to start activity " + intent);
        以及如何规避么

      本文标题:详解Activity的启动过程

      本文链接:https://www.haomeiwen.com/subject/bbfnvttx.html