activity+window+view简单说明
来源:互联网 发布:艾宾浩斯遗忘曲线软件 编辑:程序博客网 时间:2024/06/05 10:31
本章博客经过自己查了源码以及参考了别人的的些许博客,就算做一个小小的总结加深自己的体会和理解,算是个学习笔记。
window是一个抽象类,正如api所说这个类只有一个子类,也就是PhoneWindow,该子类位于com.android.internal.policy.impl包里面;查看源码可以知道Activity类有一个Window类的引用mWindow,并且可以通过getWindow()来获取这个Window对象。简单的追踪一下源码可以发现window在Activity的attach方法里面得到了初始化:
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config) { attachBaseContext(context); mFragments.attachActivity(this); mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); ............ mWindow.setWindowManager(null, mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); if (mParent != null) { mWindow.setContainer(mParent.getWindow()); } mWindowManager = mWindow.getWindowManager(); ........... }
通过上面的代码可以知道mWindow是通过PolicyManager的makeNewWindow(this)来进行初始化的,PolicyManager这个类很简单(注意该类是final类型的并且不可以通过new来初始化),该类包含了一个IPoliciy的引用sPolicy,通过反射机制对该引用进行初始化;
static { // Pull in the actual implementation of the policy at run-time try { Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME); sPolicy = (IPolicy)policyClass.newInstance(); } catch (ClassNotFoundException ex) { throw new RuntimeException( POLICY_IMPL_CLASS_NAME + " could not be loaded", ex); } catch (InstantiationException ex) { throw new RuntimeException( POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException( POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex); } }IPolicy是一个接口,该接口提供了三个方法,其中一个方法就是makeNewWindow(Context context);IPolicy的子类为Policy,该类实现了makNewWindow方法:
public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context); }
而PolicyManager的makeNewWindow就只是简单的调用sPolicy.makeNewWindow()了,他们的代码脉络很简单,追踪源代码很容易发现。其实PolicyManger就是一个简单工厂模式的应用,它在工厂模式中扮演着工厂类角色,IPolicy为抽象产品角色,它的实现类Policy就是具体产品角色了!
通过上面的说明,我们知道mWindow在attach方法中游PolicyManger的makeNewWindow方法来初始化。
当调用了attach方法过后就会调用onCreate方法了:
public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); initActionBar(); }
方法定位到了Window的setContentView,那就看看PhoneWindow类的setContentView的实现:该类聚合了两个View对象,一个是mDecor
该对象是FrameLayout的子类;另一个是mContentParent对象;
public void setContentView(int layoutResID) { if (mContentParent == null) { installDecor(); } else { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); final Callback cb = getCallback(); if (cb != null) { cb.onContentChanged(); } }这个方法先判断mContentParent是否为null,如果为null的情况下就在installDecor方法里面完成了mDecor以及mContentParent初始化工作:
private void installDecor() { if (mDecor == null) { mDecor = generateDecor(); mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); mDecor.setIsRootNamespace(true); } if (mContentParent == null) { mContentParent = generateLayout(mDecor); mTitleView = (TextView)findViewById(com.android.internal.R.id.title); if (mTitleView != null) { if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) { View titleContainer = findViewById(com.android.internal.R.id.title_container); if (titleContainer != null) { titleContainer.setVisibility(View.GONE); } else { mTitleView.setVisibility(View.GONE); } if (mContentParent instanceof FrameLayout) { ((FrameLayout)mContentParent).setForeground(null); } } else { mTitleView.setText(mTitle); } } } }
该方法先调用generateDecor方法对mDecor来进行初始化,后初始化mContentParent,在generateLayout方法里面有这么一句话可以看出mDecor跟mContentParent的关系:
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);return contentParent;
而这个findViewById方法是父类Window提供的
public View findViewById(int id) { return getDecorView().findViewById(id); }可以看出来的是从mDecor获取一个View对象来赋值给mContentParent,所以mDecor和mContentParent是父View与子View关系。mContentParent有什么用么?
继续观察 setContentView方法:
mLayoutInflater.inflate(layoutResID, mContentParent);至于inflate的具体说明见此博客,也就是说mContentParent这View是作为你的xml文件的父View,xml通过解析生成的View对象被作为mContentParent的子View通过addView添加都mContentParent上来;而由于mConentParent是mDecor子View,所以我们说真个页面的父View或者根View就是mDecor这个View。
总结:通过上面的说明Activity,Window可以得到类图关系如下:
最后简单的用图表示一下Activity PhoneWindow DecorView的关系
其实,整个代码的脉络很清晰,只要追踪一下源代码就可以很清晰的得到上面的结论。
0 0
- activity+window+view简单说明
- Activity、Window、View
- View、 window、 Activity
- activity,window,view关系
- View, Activity, Window
- android-Activity-Window-View
- Activity/Window/View
- activity,window,view
- Activity Window View的关系
- View, ViewRoot, Window, WindowManager, Activity
- Activity,Window,View的关系
- Activity、Window、View的关系
- Activity、Window、View的关系
- Activity、Window、View的关系
- Activity、Window、View的关系
- Activity、Window、View的关系
- Android : Activity,Window and View.
- Activity、Window、View的关系
- 前App Store高管揭秘:关于“苹果推荐”的七大真相
- GUI编程初步
- LeetCode #3 Longest Substring Without Repeating Characters
- [Android]View跟随屏幕旋转
- [Win32SDK基本]Button Control(4)Radio Buttons
- activity+window+view简单说明
- App Store 申请审核加速
- myeclipse快捷键
- 开源库
- HTTPS那些事(二)SSL证书
- POSIX定时器--timer_create等系列
- HTTPS那些事(三)攻击实例与防御
- 62 js文件无法引入 thinkphp $_GET页面条件判断改变选中效果
- AppStore提审攻略