ActivityThread通过调用handleLaunchActivity启动我们的目标activity
第一步 创建Activity,执行onCreate()
ActivityThread中执行performLaunchActivity方法。
Activity a = performLaunchActivity(r, customIntent);
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//通过newInstance来创建一个activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
//创建context
if (activity != null) {
//创建context
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//...
//执行activity的onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//...
}
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
转到Activity类中执行onCreate方法
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
//调用我们自己写onCreate方法
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
第二步 显示Activity,执行onResume()
在ActivityThread中首先判断第一步是否创建了Activity,如果创建了执行onResume
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
//...
}
handleResumeActivity方法源码阅读
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);
//...
//
r = performResumeActivity(token, clearHide, reason);
if (r != null) {
//...
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;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient && !a.mWindowAdded) {
a.mWindowAdded = true;
//***** 这是关键代码 WindowManager的addView方法
wm.addView(decor, l);
}
//...
}
WindowManager是连接Activity和View的桥梁
WindowManager是个接口,其实现类是WindowManagerImpl
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
//会调用global的addView方法
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
WindowManagerGlobal才是真是new出了ViewRootImpl
来看WindowManagerGlobal的addView方法
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
//...
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
//...
//***关键点,new一个ViewRoot,持有ViewRootImpl的引用
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
//添加缓存
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
//这里才是到真正要显示View布局的地方,也是在这里界面要和用户见面了!!!
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
}
throw e;
}
}
继续往下看RootViewImpl的setView()方法
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
//...
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
//就是一个关键方法,来显示view
requestLayout();
//...
}
}
}
来看看说了那么多废话的requestLayout()到底是做了些什么
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
//会检查线程,你所有的在子线程操作UI的错误都是在checkThread中爆出来的
checkThread();
mLayoutRequested = true;
//这就要马上显示了
scheduleTraversals();
}
}
//what the fuck 什么方法都没有,哪有显示方法
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
别急,我们来看有个postCallback,来看看这个runnable干嘛的,没有就不看这FUNKING CODE了!!!
final class TraversalRunnable implements Runnable {
@Override
public void run() {
//熟不熟悉的单词 doTraversal
doTraversal();
}
}
终于找到你,好像隔了几个世纪,到这里就要来执行View的绘制流程了,到这里我们的View也就绘制出来了,也是在这里我们才可以获得控件的宽高了,是在onResume之后我们才可以获取宽高,别再犯傻逼的错误了
网友评论