在 Android 開發中,NullPointerException 是最常見的崩潰之一。本文通過一個實戰案例,詳細分析 ArrayAdapter 因佈局資源 ID 與 TextView ID 不匹配導致的空指針異常,並提供修復方案。
開發者在子執行緒中讀取數據,通過 Handler 切回主執行緒更新 ListView,代碼片段如下:
arrayAdapter = new ArrayAdapter<String>(
this,
android.R.layout.activity_list_item,
android.R.id.text2,
dirs
);
handler.post(() -> direc.setAdapter(arrayAdapter));
Logcat 拋出異常堆疊:
java.lang.NullPointerException
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:353)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:323)
...
異常拋出於 ArrayAdapter.createViewFromResource(),直接原因是 android.R.layout.activity_list_item 佈局中不存在 android.R.id.text2 這個 TextView。
查閱 Android SDK 源碼可知:
android.R.layout.activity_list_item(即 simple_list_item_1.xml)僅包含一個 ID 為 text1 的 TextView。android.R.id.text2 存在於 simple_list_item_2.xml(雙行佈局)中。因此,當 Adapter 嘗試 findViewById(android.R.id.text2) 時返回 null,隨後對 null 調用 setText() 觸發 NPE。
android.R.id.text2 改為 android.R.id.text1。android.R.layout.simple_list_item_2(雙行佈局),同時保留 text2。res/layout/ 創建專屬 Item 佈局,完全掌控 ID 與樣式,避免系統資源變更風險。Handler、runOnUiThread() 或 Kotlin 協程切換至主執行緒。Adapter 與 ListView 非空。掌握系統佈局結構與 ID 對應關係,能有效避免此類低級崩潰,提升開發效率。