View繪製流程源碼解析-第一篇

繪製流程概覽

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做了什麼?
敬請期待

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章