不知道标题是否准确,即使Activity开始自己的周期,从attach开始,接着第一篇的attach点.多说一句,前面跟随思路,一步一步的打log,生成services.jar放到系统里面运行,就知道自己的判定是否正确了.
下面回到Activity的类,attach :
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
Application application, Intent intent, ActivityInfo info, CharSequence title,
Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances,
Configuration config) {
attach(context, aThread, instr, token, 0, application, intent, info, title, parent, id,
lastNonConfigurationInstances, config);
}
新建和初始化窗口:
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mWindow是Window的一个对象,但是Window本身是一个抽象类,新建一个窗体:
mWindow = PolicyManager.makeNewWindow(this);
这个开始.由PolicyManager开始:
// The static methods to spawn new policy-specific objects
public static Window makeNewWindow(Context context) {
return sPolicy.makeNewWindow(context);
}
而sPolicy是IPolicy.它是一个接口类:
/* The implementation of this interface must be called Policy and contained
* within the com.android.internal.policy.impl package */
public interface IPolicy {
public Window makeNewWindow(Context context);
public LayoutInflater makeNewLayoutInflater(Context context);
public WindowManagerPolicy makeNewWindowManager();
public FallbackEventHandler makeNewFallbackEventHandler(Context context);
}
实现类Policy :
public Window makeNewWindow(Context context) {
return new PhoneWindow(context);
}
返回了一个PhoneWindow对象.
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
获取的这个返回对象.
... ...
在进入Activity的onCreate方法:
在这个地方首先看一下下面三张图:
下面是视图的框架流程:
视窗体的组成分布:
下面的是setContentView的地位:
设置布局或者View时,最后进入PhoneWindow类:
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
}
如果不是子View,即Activity父容器未创建,则先创建Activity父容器,那么程序就会运行installDecor()方法:
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
通过generateDecor产生一个mDecor对象:
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
下面:
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
/* package */int mDefaultOpacity = PixelFormat.OPAQUE;
/** The feature ID of the panel, or -1 if this is the application's DecorView */
private final int mFeatureId;
private final Rect mDrawingBounds = new Rect();
private final Rect mBackgroundPadding = new Rect();
private final Rect mFramePadding = new Rect();
private final Rect mFrameOffsets = new Rect();
private boolean mChanging;
private Drawable mMenuBackground;
private boolean mWatchingForMenu;
private int mDownY;
private ActionMode mActionMode;
private ActionBarContextView mActionModeView;
private PopupWindow mActionModePopup;
private Runnable mShowActionModePopup;
public DecorView(Context context, int featureId) {
super(context);
mFeatureId = featureId;
}
这个DecorView是一个继承了FrameLayout的视图类.这里面记住featureId,创建以后:
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
// Set up decor part of UI to ignore fitsSystemWindows if appropriate.
mDecor.makeOptionalFitsSystemWindows();
mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
if (mTitleView != null) {
mTitleView.setLayoutDirection(mDecor.getLayoutDirection());
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
开始创建跟View,其中所有自定义View的根View, id="@android:id/content",下面:
protected ViewGroup generateLayout(DecorView decor) {
// Apply data from current theme.
TypedArray a = getWindowStyle(); ... ...
int features = getLocalFeatures();
// System.out.println("Features: 0x" + Integer.toHexString(features));
if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(... ...
这个方法很有意思,一看就知道我们平时设置Activity主题theme,SDK之类的信息是如何处理的了,开始加载设置这个窗体的风格样式(根据指定的theme和feature).
添加视窗:
View in = mLayoutInflater.inflate(layoutResource, null);
decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
由窗口顶层视窗decor添加Activity布局各个View.
这个方法可以仔细阅读,不过注意它的返回值是,mContentParent.这样整个窗体框架基本出来了.由于程序app提供的是xml,那么就需要解析并且返回view,通过下面:
View in = mLayoutInflater.inflate(layoutResource, null);
通过它解析xml,获取信息:
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
final AttributeSet attrs = Xml.asAttributeSet(parser);
Context lastContext = (Context)mConstructorArgs[0];
mConstructorArgs[0] = mContext;
View result = root;
基本的视窗就差不多了.
1> : 创建一个DecorView对象,该对象将作为整个应用窗口的根视图
2> : 创建不同的窗口修饰布局文件,并且获取Activity的布局文件该存放的地方,由该窗口修饰布局文件内id为content的FrameLayout指定 。
3> : 将Activity的布局文件添加至id为content的FrameLayout内
看过Activity周期的都会知道,Activity窗体显示出来并不是在oncreate时候,而是onResume的时候:回到ActivityManagerService类,回调onResume中:
//系统resume一个Activity时,调用此方法
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
ActivityRecord r = performResumeActivity(token, clearHide);
//...
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
然后进入Activity类:
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}