Android setContentView()源码分析

文章目录

  • [Android setContentView()源码分析](#Android setContentView()源码分析)
    • 前提
    • [setContentView() 源码分析](#setContentView() 源码分析)
    • 总结

Android setContentView()源码分析

前提

Activity 的生命周期与 ActivityThread 相关,调用 startActivity() 时,会调用 ActivityThread#performLaunchActivity(),接着调用 Activity#attach() 并在其中创建 PhoneWindow。

Activity 持有 PhoneWindow 对象,PhoneWindow 持有 DecorView。

java 复制代码
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    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.activityConfigCallback,
                    r.assistToken, r.shareableActivityToken);

    return activity;
}
java 复制代码
public class Activity {
    private Window mWindow;

    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,
                      IBinder shareableActivityToken) {

        // 创建PhoneWindow
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
    }
}
java 复制代码
public class PhoneWindow extends Window {
    private DecorView mDecor;
    ViewGroup mContentParent;
}

setContentView() 源码分析

java 复制代码
// Activity#setContentView()
public void setContentView()(@LayoutRes int layoutResID) {
    // 调用PhoneWindow#setContentView()
    getWindow().setContentView(layoutResID);
    initWindowDecorActionBar();
}

public Window getWindow() {
    return mWindow;
}
java 复制代码
// PhoneWindow#setContentView()
// 核心代码:
public void setContentView()(int layoutResID) {
    if (mContentParent == null) {
        // 初始化DecorView
        installDecor();
    } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
        mContentParent.removeAllViews();
    }
    // 将布局添加到ContentView中
    mLayoutInflater.inflate(layoutResID, mContentParent);
}
java 复制代码
// PhoneWindow#installDecor()
private void installDecor() {
    mForceDecorInstall = false;
    if (mDecor == null) {
        // 创建DecorView
        mDecor = generateDecor(-1);
    } else {
        mDecor.setWindow(this);
    }
    if (mContentParent == null) {
        // 获取ContentView
        mContentParent = generateLayout(mDecor);
    }
}
java 复制代码
// PhoneWindow#generateDecor()
protected DecorView generateDecor(int featureId) {
    Context context;
    if (mUseDecorContext) {
        Context applicationContext = getContext().getApplicationContext();
        if (applicationContext == null) {
            context = getContext();
        } else {
            context = new DecorContext(applicationContext, this);
            if (mTheme != -1) {
                context.setTheme(mTheme);
            }
        }
    } else {
        context = getContext();
    }
    // 创建DecorView,DecorView继承自FrameLayout
    return new DecorView(context, featureId, this, getAttributes());
}
java 复制代码
// PhoneWindow#generateLayout()
// 核心代码:
protected ViewGroup generateLayout(DecorView decor) {
    // 布局id
    int layoutResource;
    int features = getLocalFeatures();
   	// 省略layoutResource赋值流程,根据主题赋值
	// ...
    // 加载layoutResource生成View,并加载到DecorView中
    mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
	// 通过DecorView获取id为ID_ANDROID_CONTENT的View
    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);    

    return contentParent;
}

总结

执行流程:

  • Activity#setContentView()
  • PhoneWindow#setContentView()
  • PhoneWondow#installDecor()
    • PhoneWindow#generateDecor() 创建DecorView
    • PhoneWindow#generateLayout() 加载layoutResource并获取ContentView
  • 将自定义布局添加到ContentView中
相关推荐
longxibo4 小时前
【AIBIZ低代码平台:能长出业务系统的平台】
android·低代码·rxjava
AI_Gump12 小时前
Harness篇|DeepSeek Harness 上手机:五条安卓移植路线与 App 内 Linux 拆解
android·linux·人工智能·智能手机·deepseek
疯华整猫17 小时前
否决 Flutter 提案那天,我发现自己也说不清 Framework 管什么
android
传奇开心果编程1 天前
【Flutter踩坑排雷】第25课:ScrollController 误用坑|跳转失效、监听泄漏与“控制器未附加”
android·flutter·ios·移动开发·跨平台·dart·声明式ui
慕容雪_1 天前
Capacitor8-Android打包完整手册
android·打包·capacitor
阿杰m2 天前
Android源码第十三章:Bluetooth——沿一次发现走到控制器
android
booboosui2 天前
派活给另一个 AI:前后两次文件夹快照,就是交付清单
android
普通人62 天前
MySQL_FIND_IN_SET函数详解
android·数据库·mysql
好的佩奇2 天前
Dart 之集合元素
android·flutter·dart
Easyhood2 天前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose