首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android ArrayAdapter 過早初始化導致 Context 為 null 崩潰問題

     編輯:程式設計疑難解答

崩潰現象

Activity 啟動時直接崩潰,日誌提示 `NullPointerException` 指向 `ArrayAdapter` 構造函數傳入的 `this`(Context)為 null。

錯誤代碼

public class MainActivity extends Activity {
    private String[] str = {"one","two","three","four"};
    private GridView gv;
    // 錯誤:成員變量初始化時調用構造函數,this 尚未完全構造
    ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, str);
    // ...
}

根本原因

Java 類初始化順序:

  1. 父類靜態字段/塊
  2. 子類靜態字段/塊
  3. 父類實例字段/塊
  4. 父類構造函數
  5. 子類實例字段/塊 ← 此處執行 `new ArrayAdapter(this)`
  6. 子類構造函數

在步驟 5 時,`Activity` 的 `onCreate()` 尚未調用,`Context` 內部狀態未就緒,傳入 `this` 導致 `ArrayAdapter` 內部調用 `getSystemService()` 等方法失敗。

正確做法

方案一:在 onCreate 中初始化(推薦)

public class MainActivity extends Activity {
    private ArrayAdapter arrayAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 此時 this (Context) 完全可用
        arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, str);
        gv.setAdapter(arrayAdapter);
    }
}

方案二:懶加載獲取

private ArrayAdapter getAdapter() {
    if (arrayAdapter == null) {
        arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, str);
    }
    return arrayAdapter;
}

同類陷阱

  • `LayoutInflater.from(this)` 在字段初始化時調用
  • `getSharedPreferences()`、`getResources()` 等 Context 依賴方法
  • Fragment 中 `getActivity()` 在 `onAttach()` 前調用

最佳實踐

  1. 所有依賴 `Context` 的對象創建,**統一放在 `onCreate()` / `onAttach()` 之後**。
  2. 使用 `lateinit` (Kotlin) 或 `null` 佔位 (Java) 延遲初始化。
  3. 啟用 Android Studio「Inspect Code」檢查「Field initialization uses 'this' before constructor completes」警告。

修正後,Activity 正常啟動,GridView 正確顯示數據。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved