摘要:本文章是基于源码讲解加载显示基本流程首先上一张图给大家一个直观的了解首先一个布局页面的加载是在中的开始我们就从源码中的方法入手通过源码我们可以看到又传给了中的方法返回的是的对象我们来看中方法是一个隐藏类,在源码中中方法新创建时为空,调用方
本文章是基于Android源码6.0讲解Activity加载显示基本流程
首先上一张图给大家一个直观的了解
首先一个布局页面的加载是在Activity中的setContentView(R.layout.res)开始;
我们就从Acitvity源码中的setContentView方法入手
public void setContentView(@LayoutRes int layoutResID) { getWindow().setContentView(layoutResID); initWindowDecorActionBar(); }
通过源码我们可以看到layoutResID又传给了getWindow()中的setContentView(layoutResID)方法;
mWindow = new PhoneWindow(this); public Window getWindow() { return mWindow; }
getWindow()返回的是PhoneWindow的对象
我们来看PhoneWindow中setContentView(layoutResID)方法
PhoneWindow是一个隐藏类,在源码sources/andorid-23/com/android/internal/policy中
PhoneWindow中setContentView方法
@Override public void setContentView(int layoutResID) { if (mContentParent == null) { installDecor();//Activity新创建时mContentParent 为空,调用installDecor方法 } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) { mContentParent.removeAllViews(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID, getContext()); transitionTo(newScene); } else { mLayoutInflater.inflate(layoutResID, mContentParent); } mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } }
我们来看PhoneWindow中installDecor()方法中的关键部分
private void installDecor() { if (mDecor == null) { mDecor = generateDecor(); //@1 mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); mDecor.setIsRootNamespace(true); if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) { mDecor.postOnAnimation(mInvalidatePanelMenuRunnable); } } if (mContentParent == null) { mContentParent = generateLayout(mDecor); //@2 ... } mLayoutInflater.inflate(layoutResID, mContentParent);//@3 }
在PhoneWindow源码中声明了 private DecorView mDecor;
DecorView 是PhoneWindow中的一个内部类继承了FrameLayout,是一个帧布局
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker { ... }
@1 首先调用mDecor = generateDecor();返回的是一个 DecorView的对象,这就是所有页面的跟布局
protected DecorView generateDecor() { return new DecorView(getContext(), -1); }
@2 其次调用mContentParent = generateLayout(mDecor);
protected ViewGroup generateLayout(DecorView decor) { ... } else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) { layoutResource = R.layout.screen_simple_overlay_action_mode; } else { // Embedded, so no decoration is needed. layoutResource = R.layout.screen_simple; // System.out.println("Simple!"); } View in = mLayoutInflater.inflate(layoutResource, null); decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); mContentRoot = (ViewGroup) in; ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); ... return contentParent; }
这里的layoutResource是源码中的布局,我们来看一下R.layout.screen_simple
在sdk/platforms/android-23/data/res/layout路径中
R.layout.screen_simple就是一个简单的线性布局,通过mLayoutInflater.inflate和decor.addView添加到DecorView中,
再通过ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);把R.layout.screen_simple中id
为id/content的Framelayout赋值给contentParent
@3 最后通过mLayoutInflater.inflate(layoutResID, mContentParent);把我们写的布局添加到mContentParent中。
未完待续...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71075.html
摘要:此时再次旋转屏幕时,该不会被系统杀死和重建,只会调用。因此可通过和来判断是否被重建,并取出数据进行恢复。但需要注意的是,在取出数据时一定要先判断是否为空。只有在进程不被掉,正常情况下才会执行方法。 目录介绍 1.0.0.1 说下Activity的生命周期?屏幕旋转时生命周期?异常条件会调用什么方法? 1.0.0.2 后台的Activity被系统回收怎么办?说一下onSaveInsta...
摘要:换句话说,环境或应用程序没有处于请求操作的适当状态。项目中异常分析引发崩溃日志的流程分析解决办法常见的出现场景状态异常非法线程操作。导致的方法出来显示消息位于该消息之后,迟迟没有执行。这时候,的超时检测结束,删除了服务中的记录。 目录介绍 1.1 java.lang.UnsatisfiedLinkError找不到so库异常 1.2 java.lang.IllegalStateExce...
阅读 3564·2021-11-23 09:51
阅读 1438·2021-11-04 16:08
阅读 3527·2021-09-02 09:54
阅读 3586·2019-08-30 15:55
阅读 2572·2019-08-30 15:54
阅读 922·2019-08-29 16:30
阅读 2024·2019-08-29 16:15
阅读 2292·2019-08-29 14:05