Android中为什么在onResume之前(包括onResume)获取不到View的宽高?

Android中为什么在onResume之前(包括onResume)获取不到View的宽高?

已知点: 1.View绘制流程的起点是 ViewRootImpl#scheduleTraversals() ;
2.在onCreate里的setContentView中 确定了布局文件中有哪些对象;
3.ActivityThread的main()是应用程序的启动点,且有Activity生命周期的调用顺序;

定位点:1.找到ActivityThread#handleResumeActivity()点;
2.进入ActivityThread#performResumeActivity()这里即是调用了生命周期的onResume();
3.handleResumeActivity#performResumeActivity()之后,会获取到DecorView,View decor = r.window.getDecorView();
wm的实例是WindowManagerGlobal。

 wm.addView(decor, l);

4.WindowManagerGlobal#addView()里将我们的DecorView与ViewRootImp绑定好;
root = new ViewRootImpl(view.getContext(), display);
root.setView(view, wparams, panelParentView);
5.通过root.setView()里的 requestLayout()方法进入到scheduleTraversals(),从而再进行measure、layout、draw。

因此,看此流程可知:
在调用onResume()的时候,此时根View根本都没有与ViewRootImp绑定,没有进行measure等 操作,因此无法获取到View的宽高是正常的。

public final class ActivityThread {
……

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
    ......

    ActivityClientRecord r = performResumeActivity(token, clearHide);

    if (r != null) {
        final Activity a = r.activity;
        ......

        // If the window hasn't yet been added to the window manager,
        // and this guy didn't finish itself or start another activity,
        // then go ahead and add the window.
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) {
            try {
                willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                        a.getActivityToken());
            } catch (RemoteException e) {
            }
        }
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            ......
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            }
        } 

        ......
    }

    ......
}

......

}

你可能感兴趣的:(应用开发)