为啥在 onCreate() 方法中初始化 Array Adapter 很重要?

Posted

技术标签:

【中文标题】为啥在 onCreate() 方法中初始化 Array Adapter 很重要?【英文标题】:Why is it important to initialize Array Adapter inside the onCreate() method?为什么在 onCreate() 方法中初始化 Array Adapter 很重要? 【发布时间】:2021-08-03 15:14:23 【问题描述】:
ArrayAdapter<String> bigSquash = new ArrayAdapter<String>(this, R.layout.adapter_xml, onPointString);

每当我在 onCreate() 方法之外初始化此数组适配器时,都会生成错误,而当我在 onCreate() 方法中初始化它时,不会引发错误。 那么有人能告诉我为什么会这样吗?

【问题讨论】:

你需要发布你的代码截图。这将有助于其他人回答您的问题 咨询:***.com/help/how-to-ask。然后改进你的问题来解释 1)什么是“onCreate 之外”? (显示一些代码)和 2)什么是“产生的错误”? 【参考方案1】:

ArrayAdapter构造函数中会调用LayoutInflater.from(context) 如果activity没有onCreate,就会跑出异常,

ArrayAdapter 构造函数代码

private ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
        @IdRes int textViewResourceId, @NonNull List<T> objects, boolean objsFromResources) 
    mContext = context;
    mInflater = LayoutInflater.from(context);
    mResource = mDropDownResource = resource;
    mObjects = objects;
    mObjectsFromResources = objsFromResources;
    mFieldId = textViewResourceId;

LayoutInflater.from 代码

public static LayoutInflater from(Context context) 
    LayoutInflater LayoutInflater =
            (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (LayoutInflater == null) 
        throw new AssertionError("LayoutInflater not found.");
    
    return LayoutInflater;

activity.getSystemService 代码

@Override
public Object getSystemService(@ServiceName @NonNull String name) 
    if (getBaseContext() == null) 
        throw new IllegalStateException(
                "System services not available to Activities before onCreate()");
    

    if (WINDOW_SERVICE.equals(name)) 
        return mWindowManager;
     else if (SEARCH_SERVICE.equals(name)) 
        ensureSearchManager();
        return mSearchManager;
    
    return super.getSystemService(name);

所以你需要在activity onCreate之后调用。

【讨论】:

但是如果之前没有 OnCreate() 调用,为什么会遇到异常,会抛出什么样的异常,我们应该捕获它?我知道这些问题很多,但请尽可能多地回答! please see【参考方案2】:

这和Activity父类ContextWrapper的变量mBase的初始化有关

Activity启动过程

ActivityThread.performLaunchActivity -&gt; Activity.attach -&gt; Activity.attachBaseContext -&gt; ContextThemeWrapper.attachBaseContext -&gt; ContextWrapper.attachBaseContext -&gt; ContextWrapper.mBase init

在attach()之后会调用Activity的onCreate()方法

如果在mBase初始化之前调用Activity的getSystemService(),会因为mBase变量为空而发生异常

new ArrayAdapter(activity) -&gt; LayoutInflater.from(context) -&gt; Activity.getSystemService -&gt; Activity.getBaseContext is null throw IllegalStateException

如果需要更详细的信息,请查看Activity的启动过程

【讨论】:

以上是关于为啥在 onCreate() 方法中初始化 Array Adapter 很重要?的主要内容,如果未能解决你的问题,请参考以下文章

android 开发中 使用Application类 为啥OnCreate()方法没被调用?

为啥说安卓activity的onCreate()方法 只调用一次

为啥在 setContentView() 之后 UI 不加载,而是在 onCreate() 执行之后加载?

js初始化Array为啥要设定长度

为啥android fragment 不调用 oncreateview方法

android中的fragment是先执行oncreate还是oncreateview