美文网首页
浅析Android布局流程

浅析Android布局流程

作者: ZoranLee | 来源:发表于2021-05-06 12:21 被阅读0次
  • ActivityThread
  • PhoneWindow

Activity启动核心实现

  • performLaunchActivity
/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

..省略代码....

//创建上下文
 ContextImpl appContext = createBaseContextForActivity(r);

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();

//创建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);
            }
        }
...省略代码...

Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
//创建window
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }

}

 if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();//这时候window还是空
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
...省略代码...
}
//activity关联window
activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);
  • 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, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
...省略代码...
mWindow = new PhoneWindow(this, window, activityConfigCallback);
...省略代码...
}
  • ActivityThread
    callActivityOnCreate Activity创建成功

 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

PhoneWindow

 /**
     * Constructor for main window of an activity.
     */
    public PhoneWindow(Context context, Window preservedWindow,
            ActivityConfigCallback activityConfigCallback) {

}


public void setContentView(View view) {}

public void setContentView(View view, ViewGroup.LayoutParams params) {
 if (mContentParent == null) {
            installDecor();//
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }

}

private void installDecor() {
//初始化DecorView
if (mDecor == null) {
            mDecor = generateDecor(-1);
...省略代码...
       
        } else {
            mDecor.setWindow(this);
        }
}

 if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);
}

mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);

void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
...省略代码...
final View root = inflater.inflate(layoutResource, null);
...省略代码...

addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}

mLayoutInflater.inflate(layoutResID, mContentParent);

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {

View view = tryInflatePrecompiled(resource, res, root, attachToRoot);

// Temp is the root view that was found in the xml
                    final View temp = createViewFromTag(root, name, inflaterContext, attrs);
}

View tryInflatePrecompiled(@LayoutRes int resource, Resources res, @Nullable ViewGroup root,
        boolean attachToRoot) {
params = root.generateLayoutParams(attrs);

 if (attachToRoot) {
                        root.addView(view, params);
                    } else {
                        view.setLayoutParams(params);
                    }
}
/*
root==null    构建的view将是一个独立的个体,属性无效
root!=null  &&  attachToRoot==false
                     1.属性值会依托于root构建,所以此时的xml根布局的属性有效
                     2.根布局产生的view不是root的子布局
root!=null  &&  attachToRoot==true
                     1.属性值会依托于root构建,所以此时的xml根布局的属性有效
                     2.根布局产生的view是root的子布局,通过addView实现
*/



View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, boolean ignoreThemeAttr) {
view = createView(context, name, null, attrs);
}

 public final View createView(@NonNull Context viewContext, @NonNull String name,
            @Nullable String prefix, @Nullable AttributeSet attrs){
//使用反射调用2个参数的构造方法实例化view对象
final View view = constructor.newInstance(args);
return view;
}

相关文章

网友评论

      本文标题:浅析Android布局流程

      本文链接:https://www.haomeiwen.com/subject/yzbrdltx.html