Android四大组件之一:Activity

来源:互联网 发布:赖昌星 红楼 知乎 编辑:程序博客网 时间:2024/04/30 15:13

本文主要讲解activity的生命周期,启动模式和工作过程

1.生命周期,主要分为正常情况下的生命周期和异常情况下的生命周期

正常情况下的生命周期:

谈到生命周期,不得不提到下面的图片,相比很多人都已经很了解了,就不多做介绍了


但我还要提一下

1.如果activity采用了透明的主题,那么当前activity、不会调用onStop方法

2.A启动B,B是在A调用了onPause之后才会启动,onCreat-onStart-onResume,然后调用A的onStop方法。所以我们不能在onPause内做重量级的操作,这样会影响新界面的开启,如果必须要做最好在onStop中,但也尽量少做。


异常情况下的生命周期:

1.资源相关的系统配置发生改变导致Activity被杀死后重建(横竖屏切换)

2.资源内存不足导致activity被杀死



onSaveInstanceState这个方法是在onDestory之前调用的和onPause没有关系,但实际基本都是onPause之后,onStop之前调用

onRestoreInstanceState是在onStart之后,onResume之前调用


2.activity的启动模式

standard:标准模式,Activity默认会进入启动它的Activity所属的任务栈中,也就是谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。

当我们用ApplicationContext去启动standard模式的activity时会报错,因为非Activity类型的Context(如:ApplicationCotext)并没有任务栈。

解决办法:使用FLAG_ACTIVITY_NEW_TASK标记,其实也就是在代码中改变了activity的启动模式,改成了singleTask的启动模式了。



singleTop:栈顶复用模式,ABC再开启C,还是ABC而不是ABCC。

singleTask:栈内复用模式,如果A是singleTask模式,那么启动A时,先回判断是否存在A需要的栈,不存在则创建一个任务栈并创建A实例放入栈中;存在则判断栈内是否存在A的实例,不存在则创建A实例放入栈中,存在将A调到栈顶并调用它的onNewIntent方法。(将栈内A上面的Activity全部清除)


singleInstance:单实例模式,栈内只有一个此模式的activity。

最后说一下taskAffinity(任务栈)和Activity的Flags:

taskAffinity一般情况下会和singleTask或者allowTaskReparenting配合使用,用于给activity设置任务栈,默认的任务栈是包名;

allowTaskReparenting用来标记Activity能否从启动的Task移动到taskAffinity指定的Task,默认是继承至application中的allowTaskReparenting=false,如果为true,则表示可以更换;false表示不可以。

引用网上的解释例子:

         一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。

Activity的Flags(常用的):

1.FLAG_ACTIVITY_NEW_TASK   相当于singleTask

2.FLAG_ACTIVITY_CLEAR_TOP   一般和FLAG_ACTIVITY_NEW_TASK配合使用,清除上面的activity

3.FLAG_ACTIVITY_SINGLE_TOP    相当于singleTop

4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS    就是长按android的home键,然后清除刚才看的应用,这个属性的作用恰恰就是让你在长按home键的时候在弹出的应用列表中隐藏你的应用,达到隐藏应用程序进行的目的。(和android:excludeFromRecents="true"功能一样)

本人测试了一下:

android:excludeFromRecents="true"android:launchMode="singleInstance"

这样才管用,可能是excludefromrecents要配合singleInstance才可以(不知道是不是这样的,不太确认)


3.activity的启动过程

activity是一种展示型组件,用于向用户直接展示一个界面,并且可以根据用户输入的信息进行交互。

我们通常是通过startActivity或者startActivityForResult来启动一个新activity,而它们又有好几种重载方法,但最终都会调用到Activity类中startActivityForResult的方法:

(1)在Activity.java文件中:

  1. @Override  
  2. public void startActivity(Intent intent, Bundle options) {  
  3.     if (options != null) {  
  4.         startActivityForResult(intent, -1, options);  
  5.     } else {  
  6.         // Note we want to go through this call for compatibility with  
  7.         // applications that may have overridden the method.  
  8.         startActivityForResult(intent, -1);  
  9.     }  

  1. public void startActivityForResult(Intent intent, int requestCode, Bundle options) {  
  2.     /* 
  3.      * mParent代表的是ActivityGroup, 
  4.      * ActivityGroup最开始被用来在一个界面中嵌入多个Activity, 
  5.      * 但是其在API13中已经被废弃了,系统推荐采用Fragment来代替ActivityGroup。 
  6.      * */  
  7.     if (mParent == null) {  
  8.         /* 
  9.          * mMainThread.getApplicationThread()这个参数,它的类型是ApplicationThread, 
  10.          * ApplicationThread是ActivityThread的一个内部类, 
  11.          * 在后面的分析中可以发现,ApplicationThread和ActivityThread在Activity的启动过程中发挥着很重要的作用。 
  12.          * */  
  13.         Instrumentation.ActivityResult ar =  
  14.                 /* 
  15.                  * 所以说Activity的启动过程转移到了Instrumentation中的execStartActivity方法: 
  16.                  * */  
  17.             mInstrumentation.execStartActivity(  
  18.                 this, mMainThread.getApplicationThread(), mToken, this,  
  19.                 intent, requestCode, options);  
  20.         if (ar != null) {  
  21.             mMainThread.sendActivityResult(  
  22.                 mToken, mEmbeddedID, requestCode, ar.getResultCode(),  
  23.                 ar.getResultData());  
  24.         }  
  25.         if (requestCode >= 0) {  
  26.             // If this start is requesting a result, we can avoid making  
  27.             // the activity visible until the result is received.  Setting  
  28.             // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the  
  29.             // activity hidden during this time, to avoid flickering.  
  30.             // This can only be done when a result is requested because  
  31.             // that guarantees we will get information back when the  
  32.             // activity is finished, no matter what happens to it.  
  33.             mStartedActivity = true;  
  34.         }  
  35.   
  36.         final View decor = mWindow != null ? mWindow.peekDecorView() : null;  
  37.         if (decor != null) {  
  38.             decor.cancelPendingInputEvents();  
  39.         }  
  40.         // TODO Consider clearing/flushing other event sources and events for child windows.  
  41.     } else {  
  42.         if (options != null) {  
  43.             mParent.startActivityFromChild(this, intent, requestCode, options);  
  44.         } else {  
  45.             // Note we want to go through this method for compatibility with  
  46.             // existing applications that may have overridden it.  
  47.             mParent.startActivityFromChild(this, intent, requestCode);  
  48.         }  
  49.     }  
  50. }  

(2)Instrumentation的execStartActivity方法:在Instrumentation.java文件中。

  1. public ActivityResult execStartActivity(  
  2.         Context who, IBinder contextThread, IBinder token, Activity target,  
  3.         Intent intent, int requestCode, Bundle options) {  
  4.     IApplicationThread whoThread = (IApplicationThread) contextThread;  
  5.     if (mActivityMonitors != null) {  
  6.         synchronized (mSync) {  
  7.             final int N = mActivityMonitors.size();  
  8.             for (int i=0; i<N; i++) {  
  9.                 final ActivityMonitor am = mActivityMonitors.get(i);  
  10.                 if (am.match(who, null, intent)) {  
  11.                     am.mHits++;  
  12.                     if (am.isBlocking()) {  
  13.                         return requestCode >= 0 ? am.getResult() : null;  
  14.                     }  
  15.                     break;  
  16.                 }  
  17.             }  
  18.         }  
  19.     }  
  20.     try {  
  21.         intent.migrateExtraStreamToClipData();  
  22.         intent.prepareToLeaveProcess();  
  23.         /* 
  24.          * 所以启动Activity的真正实现由ActivityManagerNative.getDefault().startActivity方法来完成。 
  25.          *  
  26.          * ActivityManagerService继承自ActivityManagerNative, 
  27.          * 而ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口, 
  28.          * 因此ActivityManagerService也是一个Binder,它是IActivityManager的具体实现。 
  29.          *  
  30.          * 由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象, 
  31.          * 因此它的具体实现是ActivityManagerService。 
  32.          * 所以说Activity的启动过程又转移到了ActivityManagerService中, 
  33.          * 然后再去看ActivityManagerService的startActivity方法。 
  34.          * */  
  35.         int result = ActivityManagerNative.getDefault()  
  36.             .startActivity(whoThread, who.getBasePackageName(), intent,  
  37.                     intent.resolveTypeIfNeeded(who.getContentResolver()),  
  38.                     token, target != null ? target.mEmbeddedID : null,  
  39.                     requestCode, 0nullnull, options);  
  40.         /* 
  41.          * 检查启动Activity的结果: 
  42.          * */  
  43.         checkStartActivityResult(result, intent);  
  44.     } catch (RemoteException e) {  
  45.     }  
  46.     return null;  
  47. }  

在上面的代码中可以看到这一句:checkStartActivityResult(result, intent);我们去看看这个方法的源码:

  1. static void checkStartActivityResult(int res, Object intent) {  
  2.     if (res >= ActivityManager.START_SUCCESS) {  
  3.         return;  
  4.     }  
  5.     switch (res) {  
  6.         case ActivityManager.START_INTENT_NOT_RESOLVED:  
  7.         case ActivityManager.START_CLASS_NOT_FOUND:  
  8.             if (intent instanceof Intent && ((Intent)intent).getComponent() != null)  
  9.                 /* 
  10.                  * 这个异常错误抛出最常见了。 
  11.                  * 如果没有在AndroidManifest中注册Activity,就会抛出此异常。 
  12.                  * */  
  13.                 throw new ActivityNotFoundException(  
  14.                         "Unable to find explicit activity class "  
  15.                         + ((Intent)intent).getComponent().toShortString()  
  16.                         + "; have you declared this activity in your AndroidManifest.xml?");  
  17.             throw new ActivityNotFoundException(  
  18.                     "No Activity found to handle " + intent);  
  19.         case ActivityManager.START_PERMISSION_DENIED:  
  20.             throw new SecurityException("Not allowed to start activity "  
  21.                     + intent);  
  22.         case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:  
  23.             throw new AndroidRuntimeException(  
  24.                     "FORWARD_RESULT_FLAG used while also requesting a result");  
  25.         case ActivityManager.START_NOT_ACTIVITY:  
  26.             throw new IllegalArgumentException(  
  27.                     "PendingIntent is not an activity");  
  28.         default:  
  29.             throw new AndroidRuntimeException("Unknown error code "  
  30.                     + res + " when starting " + intent);  
  31.     }  
  32. }
(3)在ActivityManagerNative.java文件中:

ActivityManagerNative.getDefault实际上就是ActivityManagerService,因此Activity的启动过程转移到了ActivityManagerService中。

  1. /* 
  2.  * 在Instrumentation的execStartActivity中用ActivityManagerNative的getDefault来获取一个IActivityManager的对象, 
  3.  * 而且这个IActivityManager的对象其实是一个Binder对象,它的具体实现是ActivityManagerService。 
  4.  * */  
  5. static public IActivityManager getDefault() {  
  6.     return gDefault.get();  


  1. /* 
  2.  * 在ActivityManagernative中,ActivityManagerService这个Binder对象采用单例模式对外提供, 
  3.  * Singleton是一个单例的封装类, 
  4.  * 第一次调用它的get方法时它会通过create方法来初始化ActivityManagerService这个Binder对象, 
  5.  * 在后续的调用中则直接返回之前创建的对象。 
  6.  * */  
  7. private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {  
  8.     protected IActivityManager create() {  
  9.         IBinder b = ServiceManager.getService("activity");  
  10.         if (false) {  
  11.             Log.v("ActivityManager""default service binder = " + b);  
  12.         }  
  13.         /* 
  14.          * 将Binder对象转换成对应IActivityManager的AIDL接口对象: 
  15.          * */  
  16.         IActivityManager am = asInterface(b);  
  17.         if (false) {  
  18.             Log.v("ActivityManager""default service = " + am);  
  19.         }  
  20.         return am;  
  21.     }  
  22. };  
(4)ActivityManagerService的startActivity方法,在ActivityManagerService.java文件中

  1. @Override  
  2. public final int startActivity(IApplicationThread caller, String callingPackage,  
  3.         Intent intent, String resolvedType, IBinder resultTo,  
  4.         String resultWho, int requestCode, int startFlags,  
  5.         String profileFile, ParcelFileDescriptor profileFd, Bundle options) {  
  6.     /* 
  7.      * Activity的启动过程又转移到了startActivityAsUser方法中,再进去看看: 
  8.      * */  
  9.     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,  
  10.             resultWho, requestCode,  
  11.             startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());  
  12. }  


  1. @Override  
  2. public final int startActivityAsUser(IApplicationThread caller, String callingPackage,  
  3.         Intent intent, String resolvedType, IBinder resultTo,  
  4.         String resultWho, int requestCode, int startFlags,  
  5.         String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {  
  6.     enforceNotIsolatedCaller("startActivity");  
  7.     userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,  
  8.             falsetrue"startActivity"null);  
  9.     // TODO: Switch to user app stacks here.  
  10.     return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,  
  11.             resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,  
  12.             nullnull, options, userId);  
  13. }  

可以看出,Activity的启动过程转移到了ActivityStackSupervisor的startActivityMayWait方法中了,在startActivityMayWait中有去调用startActivityLocked方法,然后startActivityLocked方法又调用startActivityUncheckedLocked方法,接着startActivityUncheckedLocked又调用了ActivitStack的resumeTopActivityLocked,这个时候启动过程已经从ActivityStackSupervisor转移到了ActivitStack。

(5)ActivitStack的resumeTopActivityLocked方法如下:

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {        if (mStackSupervisor.inResumeTopActivity) {            // Don't even start recursing.            return false;        }        boolean result = false;        try {            // Protect against recursion.            mStackSupervisor.inResumeTopActivity = true;            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;                mService.updateSleepIfNeededLocked();            }            result = resumeTopActivityInnerLocked(prev, options);        } finally {            mStackSupervisor.inResumeTopActivity = false;        }        return result;    }
可以看出来resumeTopActivityLocked调用了resumeTopActivityInnerLocked方法,而resumeTopActivityInnerLocked方法又调用了ActivityStackSupervisor的startSpecificActivityLocked方法。

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);    }
可以看出来startSpecificActivityLocked方法调用了realStartActivityLocked方法。

至此,我们的调用先暂停一下,我们用一张图感观的看一下刚刚的多层调用:


(6)在ActivityStackSupervisor的realStartActivityLocked方法中有如下一段代码:

  1. /* 
  2.  * 这个app.thread的类型为IApplicationThread, 
  3.  * IApplicationThread继承了IInterface接口,所以它是一个Binder类型的接口。 
  4.  * 从IApplicationThread声明的接口方法可以看出,它的内部包含了大量启动、停止Activity的接口, 
  5.  * 此外还包含了启动和停止服务的接口, 从接口方法的命名可以知道, 
  6.  * IApplicationThread这个Binder接口的实现者完成了大量和Activity以及Service启动和停止相关的功能。 
  7.  * 而IApplicationThread的实现者就是ActivityThread中的内部类ApplicationThread。 
  8.  * 所以,绕来绕去,是用ApplicationThread中的scheduleLaunchActivity来启动Activity的。 
  9.  */  
  10. app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,  
  11.         System.identityHashCode(r), r.info, new Configuration(  
  12.                 mService.mConfiguration), r.compat,  
  13.         app.repProcState, r.icicle, results, newIntents,  
  14.         !andResume, mService.isNextTransitionForward(),  
  15.         profileFile, profileFd, profileAutoStop); 
(7)app.thread的类型为IApplicationThread,IApplicationThread继承了IInterface接口,所以它是一个Binder类型的接口。从IApplicationThread声明的接口方法可以看出,它的内部包含了大量启动、停止Activity的接口,此外还包含了启动和停止服务的接口, 从接口方法的命名可以知道,IApplicationThread这个Binder接口的实现者完成了大量和Activity以及Service启动和停止相关的功能。而IApplicationThread的实现者就是ActivityThread中的内部类ApplicationThread。所以,绕来绕去,是用ApplicationThread中的scheduleLaunchActivity来启动Activity的。

  1. private class ApplicationThread extends ApplicationThreadNative  
  2. public abstract  class ApplicationThreadNative extends Binder implements IApplicationThread 

  1. public interface IApplicationThread extends IInterface {  
  2.     void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,  
  3.             int configChanges, boolean dontReport) throws RemoteException;  
  4.     void scheduleStopActivity(IBinder token, boolean showWindow,  
  5.             int configChanges) throws RemoteException;  
  6.     void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;  
  7.     void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;  
  8.     void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)  
  9.             throws RemoteException;  
  10.     void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;  
  11.     void scheduleLaunchActivity(Intent intent, IBinder token, int ident,  
  12.             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,  
  13.             String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,  
  14.             PersistableBundle persistentState, List<ResultInfo> pendingResults,  
  15.             List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,  
  16.             ProfilerInfo profilerInfo) throws RemoteException;  
  17.     void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,  
  18.             List<ReferrerIntent> pendingNewIntents, int configChanges,  
  19.             boolean notResumed, Configuration config) throws RemoteException;  
  20.     void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException;  
  21.     void scheduleDestroyActivity(IBinder token, boolean finished,  
  22.             int configChanges) throws RemoteException;  
  23.     void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,  
  24.             int resultCode, String data, Bundle extras, boolean sync,  
  25.             int sendingUser, int processState) throws RemoteException;  
  26.     static final int BACKUP_MODE_INCREMENTAL = 0;  
  27.     static final int BACKUP_MODE_FULL = 1;  
  28.     static final int BACKUP_MODE_RESTORE = 2;  
  29.     static final int BACKUP_MODE_RESTORE_FULL = 3;  
  30.     void scheduleCreateBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo,  
  31.             int backupMode) throws RemoteException;  
  32.     void scheduleDestroyBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo)  
  33.             throws RemoteException;  
  34.     void scheduleCreateService(IBinder token, ServiceInfo info,  
  35.             CompatibilityInfo compatInfo, int processState) throws RemoteException;  
  36.     void scheduleBindService(IBinder token,  
  37.             Intent intent, boolean rebind, int processState) throws RemoteException;  
  38.     void scheduleUnbindService(IBinder token,  
  39.             Intent intent) throws RemoteException;  
  40.     void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,  
  41.             int flags, Intent args) throws RemoteException;  
  42.     void scheduleStopService(IBinder token) throws RemoteException;  
  43.     static final int DEBUG_OFF = 0;  
  44.     static final int DEBUG_ON = 1;  
  45.     static final int DEBUG_WAIT = 2;  
  46.     void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,  
  47.             ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments,  
  48.             IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,  
  49.             int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,  
  50.             Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,  
  51.             Bundle coreSettings) throws RemoteException;  
  52.     void scheduleExit() throws RemoteException;  
  53.     void scheduleSuicide() throws RemoteException;  
  54.     void scheduleConfigurationChanged(Configuration config) throws RemoteException;  
  55.     void updateTimeZone() throws RemoteException;  
  56.     void clearDnsCache() throws RemoteException;  
  57.     void setHttpProxy(String proxy, String port, String exclList,  
  58.             Uri pacFileUrl) throws RemoteException;  
  59.     void processInBackground() throws RemoteException;  
  60.     void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)  
  61.             throws RemoteException;  
  62.     void dumpProvider(FileDescriptor fd, IBinder servicetoken, String[] args)  
  63.             throws RemoteException;  
  64.     void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,  
  65.             int resultCode, String data, Bundle extras, boolean ordered,  
  66.             boolean sticky, int sendingUser, int processState) throws RemoteException;  
  67.     void scheduleLowMemory() throws RemoteException;  
  68.     void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;  
  69.     void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType)  
  70.             throws RemoteException;  
  71.     void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd)  
  72.             throws RemoteException;  
  73.     void setSchedulingGroup(int group) throws RemoteException;  
  74.     static final int PACKAGE_REMOVED = 0;  
  75.     static final int EXTERNAL_STORAGE_UNAVAILABLE = 1;  
  76.     void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException;  
  77.     void scheduleCrash(String msg) throws RemoteException;  
  78.     void dumpActivity(FileDescriptor fd, IBinder servicetoken, String prefix, String[] args)  
  79.             throws RemoteException;  
  80.     void setCoreSettings(Bundle coreSettings) throws RemoteException;  
  81.     void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;  
  82.     void scheduleTrimMemory(int level) throws RemoteException;  
  83.     void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo,  
  84.             boolean dumpDalvik, String[] args) throws RemoteException;  
  85.     void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;  
  86.     void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;  
  87.     void unstableProviderDied(IBinder provider) throws RemoteException;  
  88.     void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType)  
  89.             throws RemoteException;  
  90.     void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)  
  91.             throws RemoteException;  
  92.     void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)  
  93.             throws RemoteException;  
  94.     void setProcessState(int state) throws RemoteException;  
  95.     void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;  
  96.     void updateTimePrefs(boolean is24Hour) throws RemoteException;  
  97.     void scheduleCancelVisibleBehind(IBinder token) throws RemoteException;  
  98.     void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException;  
  99.     void scheduleEnterAnimationComplete(IBinder token) throws RemoteException;  
  100.   
  101.     String descriptor = "android.app.IApplicationThread";  
  102.   
  103.     ...  
  104. }  
(8)ActivityThread.java文件中的ApplicationThread内部类的scheduleLaunchActivity方法:scheduleLaunchActivity的实现很简单,就是发送一个启动Activity的消息交由Handler处理。这个Handler的名字很简洁,H。

<span style="white-space:pre"></span>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);        }


private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        if (DEBUG_MESSAGES) Slog.v(            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)            + ": " + arg1 + " / " + obj);        Message msg = Message.obtain();        msg.what = what;        msg.obj = obj;        msg.arg1 = arg1;        msg.arg2 = arg2;        if (async) {            msg.setAsynchronous(true);        }        mH.sendMessage(msg);    }
(9)接下来看一下Handler H对消息的处理:
  1. public void handleMessage(Message msg) {  
  2.     if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));  
  3.     switch (msg.what) {  
  4.     /* 
  5.      * 启动Activity: 
  6.      * */  
  7.         case LAUNCH_ACTIVITY: {  
  8.             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");  
  9.             ActivityClientRecord r = (ActivityClientRecord)msg.obj;  
  10.   
  11.             r.packageInfo = getPackageInfoNoCheck(  
  12.                     r.activityInfo.applicationInfo, r.compatInfo);  
  13.             handleLaunchActivity(r, null);  
  14.             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);  
  15.         } break;  
  16.         ...  
  17. }  
(10)handleLaunchActivity方法:

  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.         // If we are getting ready to gc after going to the background, well  
  3.         // we are back active so skip it.  
  4.         unscheduleGcIdler();  
  5.   
  6.   
  7.         if (r.profileFd != null) {  
  8.             mProfiler.setProfiler(r.profileFile, r.profileFd);  
  9.             mProfiler.startProfiling();  
  10.             mProfiler.autoStopProfiler = r.autoStopProfiler;  
  11.         }  
  12.   
  13.   
  14.         // Make sure we are running with the most recent config.  
  15.         handleConfigurationChanged(nullnull);  
  16.   
  17.   
  18.         if (localLOGV) Slog.v(  
  19.             TAG, "Handling launch of " + r);  
  20.         /* 
  21.          * 启动Activity终极大Boss在此!!!! 
  22.          * */  
  23.         Activity a = performLaunchActivity(r, customIntent);  
  24.   
  25.   
  26.         if (a != null) {  
  27.             r.createdConfig = new Configuration(mConfiguration);  
  28.             Bundle oldState = r.state;  
  29.             /* 
  30.              * 调用Activity的onResume方法: 
  31.              * */  
  32.             handleResumeActivity(r.token, false, r.isForward,  
  33.                     !r.activity.mFinished && !r.startsNotResumed);  
  34.   
  35.   
  36.             if (!r.activity.mFinished && r.startsNotResumed) {  
  37.                 // The activity manager actually wants this one to start out  
  38.                 // paused, because it needs to be visible but isn't in the  
  39.                 // foreground.  We accomplish this by going through the  
  40.                 // normal startup (because activities expect to go through  
  41.                 // onResume() the first time they run, before their window  
  42.                 // is displayed), and then pausing it.  However, in this case  
  43.                 // we do -not- need to do the full pause cycle (of freezing  
  44.                 // and such) because the activity manager assumes it can just  
  45.                 // retain the current state it has.  
  46.                 try {  
  47.                     r.activity.mCalled = false;  
  48.                     mInstrumentation.callActivityOnPause(r.activity);  
  49.                     // We need to keep around the original state, in case  
  50.                     // we need to be created again.  But we only do this  
  51.                     // for pre-Honeycomb apps, which always save their state  
  52.                     // when pausing, so we can not have them save their state  
  53.                     // when restarting from a paused state.  For HC and later,  
  54.                     // we want to (and can) let the state be saved as the normal  
  55.                     // part of stopping the activity.  
  56.                     if (r.isPreHoneycomb()) {  
  57.                         r.state = oldState;  
  58.                     }  
  59.                     if (!r.activity.mCalled) {  
  60.                         throw new SuperNotCalledException(  
  61.                             "Activity " + r.intent.getComponent().toShortString() +  
  62.                             " did not call through to super.onPause()");  
  63.                     }  
  64.   
  65.   
  66.                 } catch (SuperNotCalledException e) {  
  67.                     throw e;  
  68.   
  69.   
  70.                 } catch (Exception e) {  
  71.                     if (!mInstrumentation.onException(r.activity, e)) {  
  72.                         throw new RuntimeException(  
  73.                                 "Unable to pause activity "  
  74.                                 + r.intent.getComponent().toShortString()  
  75.                                 + ": " + e.toString(), e);  
  76.                     }  
  77.                 }  
  78.                 r.paused = true;  
  79.             }  
  80.         } else {  
  81.             // If there was an error, for any reason, tell the activity  
  82.             // manager to stop us.  
  83.             try {  
  84.                 ActivityManagerNative.getDefault()  
  85.                     .finishActivity(r.token, Activity.RESULT_CANCELED, null);  
  86.             } catch (RemoteException ex) {  
  87.                 // Ignore  
  88.             }  
  89.         }  
  90.     }  
(11)从上面的代码可以看出,performLaunchActivity方法最终完成了Activity对象的创建和启动过程,并且ActivityThread通过handleResumeActivity方法来调用被启动Activity的onResume这个生命周期方法,接下来主要介绍的就是performLaunchActivity这个方法了。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");/*  * 第一步:从ActivityClientRecord中获取待启动的Activity的组件信息:  * */         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);        }/*  * 第二步:通过Instrumentation的newActivity方法使用类加载器创建Activity对象。  * */         Activity activity = null;        try {            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();/*  * 通过类加载器创建Activity的实例对象:  * */            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);            }        }/*  * 第三步:通过LoadedApk的makeApplication方法来尝试创建Application对象,  * 而且一个应用只能有一个Application对象。  * Application对象的创建也是通过Instrumentation来完成的,这个过程和Activity对象的创建一样,  * 都是通过类加载器来实现的。  * Application创建完毕后,系统会通过Instrumentation的callApplicationOnCreate来调用Application的onCreate方法。  * */          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) {/*  * 第四步:创建ContextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化。  * 这里有一堆Activity运行过程中所依赖的上下文环境变量,  * 并通过Activity的attach方法来将这些环境变量与Activity相关联:  * (2)ContextImpl是一个很重要的数据结构,它是Context的具体实现,  * Context中改的大部分逻辑都是由ContextImpl来完成的。  * ContextImpl是通过Activity的attach方法来和Activity建立关联的。  * (3)此外,在attach方法中Activity还会完成Window的创建并建立自己和Window的关联,  * 这样当Window接收到外部输入事件后就可以将事件传递给Activity。  * */                 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;/*  * 第五步:调用Activity的onCreate方法:  * 到此为止,Activity也就完成了整个启动过程,  * */                 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;    }

补充:
1.当我们复写onSaveInstanceState时,在activity销毁的时候会将页面的信息保存在这个map中,ActivityClientRecord是记录了页面的相关信息,在源码中还有一个ActivityRecord也是记录页面信息,在类方法之间调用时这两个类会互相复制传递。他们里面有一个Bundle成员变量是存储信息的。
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
2.setContentView的关键代码
@Override    protected void onSaveInstanceState(Bundle outState) {        super.onSaveInstanceState(outState);        getDelegate().onSaveInstanceState(outState);    }
public AppCompatDelegate getDelegate() {        if (mDelegate == null) {            mDelegate = AppCompatDelegate.create(this, this);        }        return mDelegate;    }
public static AppCompatDelegate create(Activity activity, AppCompatCallback callback) {        return create(activity, activity.getWindow(), callback);    }
private static AppCompatDelegate create(Context context, Window window,            AppCompatCallback callback) {        final int sdk = Build.VERSION.SDK_INT;        if (sdk >= 23) {            return new AppCompatDelegateImplV23(context, window, callback);        } else if (sdk >= 14) {            return new AppCompatDelegateImplV14(context, window, callback);        } else if (sdk >= 11) {            return new AppCompatDelegateImplV11(context, window, callback);        } else {            return new AppCompatDelegateImplV7(context, window, callback);        }    }
在AppCompatDelegateImplV7中有setContentView方法
@Override    public void setContentView(int resId) {        ensureSubDecor();//获取mSubDeor,是否显示通知栏,actionbar,float等信息        ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);//获取content的布局,放我们的布局        contentParent.removeAllViews();        LayoutInflater.from(mContext).inflate(resId, contentParent);        mOriginalWindowCallback.onContentChanged();//window的回调    }

启动Activity的整体流程:
startActivity —— (startActivity中调用)startActivityForResult —— (startActivityForResult中调用)Instrumentation.execStartActivity ——(execStartActivity中调用)ActivityManagerNative.getDefault().startActivity也就相当于ActivityManagerService的startActivity(IPC)——(startActivity中调用)startActivityAsUser ——(startActivityAsUser中调用)ActivityStackSupervisor.startActivityMayWait —— (startActivityMayWait中调用)startActivityLocked —— (startActivityLocked 中调用)startActivityUncheckedLocked —— (startActivityUncheckedLocked 中调用)ActivityStack的resumeTopActivityLocked(此时已经从ActivityStackSupervisor转移到了ActivityStack) —— (resumeTopActivityLocked中调用)resumeTopActivityInnerLocked —— (resumeTopActivityInnerLocked中调用)ActivityStackSupervisor的startSpecificActivityLocked(此时又从ActivityStack转移到了ActivityStackSupervisor) —— (startSpecificActivityLocked中调用)realStartActivityLocked —— (realStartActivityLocked中调用)app.thread.scheduleLaunchActivity(app.thread也就是IApplicationThread)(也就是ApplicationThread的scheduleLaunchActivity)——  (scheduleLaunchActivity中调用)queueOrSendMessage —— Handler H的handleLaunchActivity —— (handleLaunchActivity 中调用)performLaunchActivity ——(execStartActivity中调用)checkStartActivityResult

声明:ActivityManagerService是Binder,ApplicationThread是Binder。

参考:http://blog.csdn.net/zizidemenghanxiao/article/details/50639025

0 0
原创粉丝点击