AndroidではなぜonResumeの前(onResumeを含む)にViewの幅が得られないのですか?
2424 ワード
AndroidではなぜonResumeの前(onResumeを含む)にViewの幅が得られないのですか?
既知のポイント:1.Viewペイントプロセスの開始点は、View RootImpl#scheduleTraversals()です.2.onCreateのsetContentViewで、レイアウトファイルにどのオブジェクトがあるかを決定します.3.Activity Threadのmain()はアプリケーションの起動点であり、Activityライフサイクルの呼び出し順序がある.
位置決め点:1.Activity Thread#handleResumeActivity()ポイントを見つけます.2.Activity Thread#performResumeActivity()ここでライフサイクルが呼び出されたonResume()に入ります.3.handleResumeActivity#performResumeActivity()の後、DecorView、View decor=r.windowが取得されます.getDecorView(); wmの例はWindowManagerGlobalである.
4.WindowManagerGlobal#addView()では、私たちのDecorViewをView RootImpにバインドします.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 { ……
}
既知のポイント:1.Viewペイントプロセスの開始点は、View RootImpl#scheduleTraversals()です.2.onCreateのsetContentViewで、レイアウトファイルにどのオブジェクトがあるかを決定します.3.Activity Threadのmain()はアプリケーションの起動点であり、Activityライフサイクルの呼び出し順序がある.
位置決め点:1.Activity Thread#handleResumeActivity()ポイントを見つけます.2.Activity Thread#performResumeActivity()ここでライフサイクルが呼び出されたonResume()に入ります.3.handleResumeActivity#performResumeActivity()の後、DecorView、View decor=r.windowが取得されます.getDecorView(); wmの例はWindowManagerGlobalである.
wm.addView(decor, l);
4.WindowManagerGlobal#addView()では、私たちのDecorViewをView RootImpにバインドします.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);
}
}
......
}
......
}
......
}