源码分析 --- Activity的启动过程

 我们平时通过调用startActivity可以启动一个Activity,但是系统内部是如何启动这个Activity的?每个Activity也是一个对象,这个对象是啥时候被创建的(也就是说它的构造方法是什么时候被调用的)?为什么onCreate是Activity的执行入口?所有的这一切都被系统封装好了。

 在分析之前,先介绍几个类:

Instrumentation类: startActivity方法的真正实现在Activity中的Instrumentation类对象,用来辅助Activity完成启动Activity的过程

         activity中的定义: private Instrumentation mInstrumentation;

ActivityThread(包含ApplicationThread + ApplicationThreadNative + IApplicationThread):真正启动Activity的实现都在这里

           activity中的定义: ActivityThread mMainThread        

源码分析

首先看入口

code:Activity#startActivity

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public void startActivity(Intent intent) {
     startActivity(intent, null );
}
 
@Override
public void startActivity(Intent intent, Bundle options) {
     if (options != null ) {
         startActivityForResult(intent, - 1 , options);
     } else {
         startActivityForResult(intent, - 1 );
     }
}
 
public void startActivityForResult(Intent intent, int requestCode) {
     startActivityForResult(intent, requestCode, null );
}

可以看到最终startActivity是 由startActivityForResult来实现的


   
接着看 startActivityForResult的实现源码

code:Activity#startActivityForResult

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
     //一般的Activity其mParent为null,mParent常用在ActivityGroup中,ActivityGroup已废弃
     if (mParent == null ) {
         //这里会启动新的Activity,核心功能都在mMainThread.getApplicationThread()中完成
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
// mMainThread就是ActivityThread的实例
                 this , mMainThread.getApplicationThread(), mToken, this ,
                 intent, requestCode, options);
         if (ar != null ) {
             //发送结果,即onActivityResult会被调用
             mMainThread.sendActivityResult(
                 mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                 ar.getResultData());
         }
         if (requestCode >= 0 ) {
             mStartedActivity = true ;
         }
 
         final View decor = mWindow != null ? mWindow.peekDecorView() : null ;
         if (decor != null ) {
             decor.cancelPendingInputEvents();
         }
         // TODO Consider clearing/flushing other event sources and events for child windows.
     } else {
         //在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的
         if (options != null ) {
             mParent.startActivityFromChild( this , intent, requestCode, options);
         } else {
             // Note we want to go through this method for compatibility with
             // existing applications that may have overridden it.
             mParent.startActivityFromChild( this , intent, requestCode);
         }
     }
}

code:Instrumentation#execStartActivity

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public ActivityResult execStartActivity(
         Context who, IBinder contextThread, IBinder token, Activity target,
         Intent intent, int requestCode, Bundle options) {
     //核心功能在这个whoThread中完成,其内部scheduleLaunchActivity方法用于完成activity的打开
     IApplicationThread whoThread = (IApplicationThread) contextThread;
     if (mActivityMonitors != null ) {
         synchronized (mSync) {
             //先查找一遍看是否存在这个activity
             final int N = mActivityMonitors.size();
            
              for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
         }
     }
     try {
         intent.migrateExtraStreamToClipData();
         intent.prepareToLeaveProcess();
         //这里才是真正打开activity的地方,核心功能在whoThread中完成。
         int result = ActivityManagerNative.getDefault()
             .startActivity(whoThread, who.getBasePackageName(), intent,
                     intent.resolveTypeIfNeeded(who.getContentResolver()),
                     token, target != null ? target.mEmbeddedID : null ,
                     requestCode, 0 , null , null , options);
         //这个方法是专门抛异常的,它会对启动activity的结果进行检查,如果无法打开activity,
         //则抛出诸如ActivityNotFoundException类似的各种异常
         checkStartActivityResult(result, intent);
     } catch (RemoteException e) {
     }
     return null ;
}</n;>
checkStartActivityResult,它也专业抛异常的,看代码,其中最熟悉的是Unable to find explicit activity class,如果你在xml中没有注册目标activity,此异常将会抛出。就是这个方法抛出来的。

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);
         default :
             throw new AndroidRuntimeException(Unknown error code
                     + res +  when starting  + intent);
     }
}




接下来我们要去看看IApplicationThread,因为核心功能由其内部的scheduleLaunchActivity方法来完成,由于IApplicationThread是个接口,所以,我们需要找到它的实现类,它就是ActivityThread中的内部类ApplicationThread,看下它的继承关系:

private class ApplicationThread extends ApplicationThreadNative;

public abstract class ApplicationThreadNative extends Binder implements IApplicationThread;

可以发现,ApplicationThread还是间接实现了IApplicationThread接口,先看下这个类的结构

data-cke-saved-src=/uploadfile/Collfiles/20140113/20140113100359116.png

看完ApplicationThread的大致结构,我们应该能够猜测到,Activity的生命周期中的resume、newIntent、pause、stop等事件都是由它触发的,事实上,的确是这样的。这里,我们为了说明问题,仅仅看scheduleLaunchActivity方法

code:ApplicationThread#scheduleLaunchActivity

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
         ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
         int procState, Bundle state, List<resultinfo> pendingResults,
         List<intent> pendingNewIntents, boolean notResumed, boolean isForward,
         String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
 
     updateProcessState(procState, false );
  //
     ActivityClientRecord r = new ActivityClientRecord();
 
     r.token = token;
     r.ident = ident;
     r.intent = intent;
     r.activityInfo = info;
     r.compatInfo = compatInfo;
     r.state = state;
 
     r.pendingResults = pendingResults;
     r.pendingIntents = pendingNewIntents;
 
     r.startsNotResumed = notResumed;
     r.isForward = isForward;
 
     r.profileFile = profileName;
     r.profileFd = profileFd;
     r.autoStopProfiler = autoStopProfiler;
 
     updatePendingConfiguration(curConfig);
 
     queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}</intent></resultinfo>

说明:上述代码很好理解,构造一个activity记录,然后发送一个消息,所以,我们要看看Handler是如何处理这个消息的,现在转到这个Handler,它有个很短的名字叫做H

code:ActivityThread#H

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//这个类太长,我只帖出了我们用到的部分
private class H extends Handler {
 
     public void handleMessage(Message msg) {
         if (DEBUG_MESSAGES) Slog.v(TAG, >>> handling:  + codeToString(msg.what));
         switch (msg.what) {
             //这里处理LAUNCH_ACTIVITY消息类型
             case LAUNCH_ACTIVITY: {
                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityStart);
                 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
 
                 r.packageInfo = getPackageInfoNoCheck(
                         r.activityInfo.applicationInfo, r.compatInfo);
                 //这里处理startActivity消息
                 handleLaunchActivity(r, null );
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             } break ;
             case RELAUNCH_ACTIVITY: {
                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityRestart);
                 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                 handleRelaunchActivity(r);
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             } break ;
             case PAUSE_ACTIVITY:
                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityPause);
                 handlePauseActivity((IBinder)msg.obj, false , msg.arg1 != 0 , msg.arg2);
                 maybeSnapshot();
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                 break ;
             ...
         }
}

说明:看来还要看handleLaunchActivity

code:ActivityThread#handleLaunchActivity

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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.
     unscheduleGcIdler();
 
     if (r.profileFd != null ) {
         mProfiler.setProfiler(r.profileFile, r.profileFd);
         mProfiler.startProfiling();
         mProfiler.autoStopProfiler = r.autoStopProfiler;
     }
 
     // Make sure we are running with the most recent config.
     handleConfigurationChanged( null , null );
 
     if (localLOGV) Slog.v(
         TAG, Handling launch of  + r);
     //performLaunchActivity真正完成了activity的调起,
     //同时activity会被实例化,并且onCreate会被调用
     Activity a = performLaunchActivity(r, customIntent);
 
     if (a != null ) {
         r.createdConfig = new Configuration(mConfiguration);
         Bundle oldState = r.state;
         //看到没,目标activity的onResume会被调用
         handleResumeActivity(r.token, false , r.isForward,
                 !r.activity.mFinished && !r.startsNotResumed);
 
         if (!r.activity.mFinished && r.startsNotResumed) {
           
             try {
                 r.activity.mCalled = false ;
                 //同时,由于新activity被调起了,原activity的onPause会被调用
                 mInstrumentation.callActivityOnPause(r.activity);
           
                 if (r.isPreHoneycomb()) {
                     r.state = oldState;
                 }
                 if (!r.activity.mCalled) {
                     throw new SuperNotCalledException(
                         Activity  + r.intent.getComponent().toShortString() +
                          did not call through to super .onPause());
                 }
 
             } catch (SuperNotCalledException e) {
                 throw e;
 
             } catch (Exception e) {
                 if (!mInstrumentation.onException(r.activity, e)) {
                     throw new RuntimeException(
                             Unable to pause activity
                             + r.intent.getComponent().toShortString()
                             + :  + e.toString(), e);
                 }
             }
             r.paused = true ;
         }
     } else {
         // If there was an error, for any reason, tell the activity
         // manager to stop us.
         try {
             ActivityManagerNative.getDefault()
                 .finishActivity(r.token, Activity.RESULT_CANCELED, null );
         } catch (RemoteException ex) {
             // Ignore
         }
     }
}

说明:关于原activity和新activity之间的状态同步,如果大家感兴趣可以自己研究下,因为逻辑太复杂,我没法把所有问题都说清楚,否则就太深入细节而淹没了整体逻辑,研究源码要的就是清楚整体逻辑。下面看最后一个方法,这个方法是activity的启动过程的真正实现。
code:ActivityThread#performLaunchActivity

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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);
     }
     //首先从intent中解析出目标activity的启动参数
     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的实例,用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象
         //其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。
         activity = mInstrumentation.newActivity(
                 cl, component.getClassName(), r.intent);
         StrictMode.incrementExpectedActivityCount(activity.getClass());
         r.intent.setExtrasClassLoader(cl);
         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);
 
             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被启动了,接下来的流程就是Activity的生命周期了,
             //本文之前已经提到,其生命周期的各种状态的切换由ApplicationThread内部来完成
             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.state != null ) {
                     mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                 }
             }
             if (!r.activity.mFinished) {
                 activity.mCalled = false ;
                 mInstrumentation.callActivityOnPostCreate(activity, r.state);
                 if (!activity.mCalled) {
                     throw new SuperNotCalledException(
                         Activity  + r.intent.getComponent().toShortString() +
                          did not call through to super .onPostCreate());
                 }
             }
         }
         r.paused = true ;
 
         mActivities.put(r.token, r);
 
     } catch (SuperNotCalledException e) {
         throw e;
 
     } catch (Exception e) {
         if (!mInstrumentation.onException(activity, e)) {
             throw new RuntimeException(
                 Unable to start activity  + component
                 + :  + e.toString(), e);
         }
     }
 
     return activity;
}
看下 Instrumentation类中newActivity方法的实现

public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
}

可以看到系统创建activity实例也是通过类加载器反射调用的。

返回这个对象后,后面就调用这个对象的onCreate方法

动态加载中就是模拟了系统的这种行为来反射创建对象和启动onCreate方法.

但是只是模拟了这2步。和系统启动来说少了很多其他的初始化的工作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值