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中
相关推荐
Yeah_0day4 分钟前
移动安全Android——客户端数据安全
android·客户端数据安全·本地文件权限配置·本地文件内容安全·本地日志内容安全
Leoysq34 分钟前
Unity链接Mysql 数据库实现注册登录
android·adb
Yeah_0day2 小时前
移动安全Android——客户端静态安全
android·app测试·安卓客户端测试·组件导出安全测试·安装包签名·反编译保护·应用完整性校验
奔跑吧 android8 小时前
【android bluetooth 协议分析 02】【bluetooth hal 层详解 6】【bt_vendor_opcode_t 介绍】
android·hal·bt·aosp13·hidl_1.0
zhifanxu12 小时前
Android开发常用Kotlin高级语法
android·开发语言·kotlin
qq_3364117512 小时前
【笔记】Trae+Andrioid Studio+Kotlin开发安卓WebView应用
android·笔记·kotlin
Tony__Ferguson13 小时前
数据结构——优先级队列(PriorityQueue)
android·java·数据结构
熙曦Sakura16 小时前
【MySQL】用户管理
android·mysql·adb
xiangxiongfly91518 小时前
Android 倒计时总结
android·倒计时·flow·timer·handler·countdowntimer
AI新视界18 小时前
MySQL高可用革命:Orchestrator实现零干预的故障转移与智能拓扑管理
android