View绘制流程源码解析-第一篇
文章目录
- 绘制流程概览
- Android启动流程分析
绘制流程概览
Android程序启动 -> Activity加载并调用生命周期onCreate -> Activity调用setContentView -> UI绘制
Android启动流程分析
我们都知道Android程序的启动入口是ActivityThread.main函数,那么看一看main函数是如何进行启动的。
ActivityThread.class
public static void main(String[] args) { … ActivityThread thread = new ActivityThread(); thread.attach(false); …}private void attach(boolean system) { … final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); }…}
由上面的源码可知,我们在main函数中做了两件事情:
- 生成一个ActivityThread对象
- 调用该对象的attach方法
在attach方法中,也做了两件事情:
- 获取了IActivityManager的对象实例
- 执行该对象的attachApplication方法
通过ActivityManager.getService()获取到Activity管理器接口对象,那么如何拿到的呢?我们来看下源码实现:
ActivityManager.class
/** * @hide */public static IActivityManager getService() { return IActivityManagerSingleton.get();}private static final Singleton IActivityManagerSingleton = new Singleton() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
- 服务管理器通过getService拿到了ActivityService 的IBinder对象,通过跨进程获取到am对象。
- mgr.attachApplication(mAppThread)是将ApplicationThread和ActivityManagertService相关联。
在APP进程启动之后,AMS便会跨binder调用到ApplicationThread的scheduleLaunchActivity,启动Activity。
详细的介绍请参照深入理解Activity——Token之旅
通过上面的分析,我们知道ApplicationThread这个对象在启动过程中起着至关重要的作用,来看下它的源码:
ApplicationThread类里面都干了什么事情?
ApplicationThread.class
private class ApplicationThread extends IApplicationThread.Stub { public final void schedulePauseActivity(IBinder token, boolean finished, ... public final void scheduleStopActivity(IBinder token, boolean showWindow, ... @Override public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ......
如上图所示,一堆的schedule方法,按照字面翻译,我们可以猜测出,这个是在Activity状态变化时去调用的方法。
在诸多的schedule方法里面,根据注释得知,scheduleLaunchActivity是在Activity加载的时候调用,我们来看一下:
ApplicationThread.class
// 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 pendingResults, List pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); ... updatePendingConfiguration(curConfig); sendMessage(H.LAUNCH_ACTIVITY, r); }
根据代码我们可以分析
- 创建了ActivityClientRecord对象
- 将ActivityClientRecord对象以及标志位LAUNCH_ACTIVITY发送出去
ApplicationThread.class
private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); }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); }final H mH = new H();private class H extends Handler {...}
通过以上代码可以知道,将创建的ActivityClientRecord对象以及标志位通过handler发送出去,那我们顺着找到mH的handleMessage方法
private class H extends Handler {...public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { ... final ActivityClientRecord r = (ActivityClientRecord) msg.obj; ... handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); ... } break; ... } ... } private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { ... Activity a = performLaunchActivity(r, customIntent); ...} private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ...}
对应着LAUNCH_ACTIVITY,调用到了handleLaunchActivity函数-> performLaunchActivity函数,在performLaunchActivity函数中,我们可以看到 mInstrumentation.callActivityOnCreate的字样,猜的没错的话,这就是调用Activity的onCreate函数的入口了,我们看下源码:
Instrumentation.class
/** * Perform calling of an activity's {@link Activity#onCreate} * method. The default implementation simply calls through to that method. * @param activity The activity being created. * @param icicle The previously frozen state (or null) to pass through to * @param persistentState The previously persisted state (or null) */ public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); activity.performCreate(icicle, persistentState); postPerformCreate(activity); }
Activity.class
final void performCreate(Bundle icicle) { performCreate(icicle, null); } final void performCreate(Bundle icicle, PersistableBundle persistentState) { ... if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } ... }public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { onCreate(savedInstanceState); }
总结一下调用关系,Instrumentation. callActivityOnCreate-> Activity. performCreate->Activity.onCreate。
到此为止,我们的整个APP已经成功启动啦~
总结一下:
2.Activity调用setContentView做了什么?
敬请期待
更多相关文章
- 关于getSystemService
- 关于使用AccountManager的remove删除Android帐号的细节
- Android利用activity启动模式退出整个应用
- 2011.07.12(3)——— android ui的一些概念
- Android中的JSONObject和JSONArray的使用
- 关于 android Intent 传对象和对象数组的一些操作
- Android的USB系统简单分析之一
- android webview js不执行原因解析
- android组件之Service