UI绘制流程源码解析

绘制流程概览

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<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @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<ResultInfo> pendingResults, List<ReferrerIntent> 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已经成功启动啦~
总结一下:
APP启动到调用Activity.create函数调用总结.png

2.Activity调用setContentView做了什么?
敬请期待

猜你喜欢

转载自blog.csdn.net/Android_Glimmer/article/details/89677581
今日推荐