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

Android ArrayAdapter 在 onCreate 中添加數據導致崩潰:UI 未初始化完成的競態條件

     編輯:程式設計綜合問答

崩潰原因分析

在 onCreate 中直接調用 adapter.add() 會觸發 notifyDataSetChanged(),但此時 ListView 尚未完成佈局初始化,導致崩潰。

錯誤代碼

adapter = new ArrayAdapter<AlarmData>(getContext(), android.R.layout.simple_list_item_1);
lvListView.setAdapter(adapter);
adapter.add(new AlarmData(System.currentTimeMillis())); // 崩潰點

正確方案:預先構建數據列表

// 1. 先準備數據
List<AlarmData> dataList = new ArrayList<>();
dataList.add(new AlarmData(System.currentTimeMillis()));

// 2. 再創建適配器並綁定數據
adapter = new ArrayAdapter<AlarmData>(this, 
    android.R.layout.simple_list_item_1, dataList); // 傳入列表

// 3. 最後設置給 ListView
lvListView.setAdapter(adapter);

關鍵修正點

  • 構造函數傳入列表:ArrayAdapter(Context, int, List<T>) 內部直接持有引用,無需後續 add()
  • Context 使用 this (Activity):原代碼 getContext() 返回 null 會導致 NPE
  • 避免在 UI 未就緒時操作適配器:onCreate 階段 View 尚未 attach 到窗口

進階:動態添加數據的正確姿勢

// 按鈕點擊添加新鬧鐘
btnAddAlarm.setOnClickListener(v -> {
    AlarmData newAlarm = new AlarmData(System.currentTimeMillis());
    dataList.add(newAlarm);        // 修改數據源
    adapter.notifyDataSetChanged(); // 通知 UI 更新
});

補充:getContext() 返回 null 的問題

// 原代碼錯誤
private Context getContext() { return null; }

// 修正:直接使用 Activity 實例 (this) 或 getApplicationContext()
adapter = new ArrayAdapter<>(MainActivity.this, ...);

總結

「先備數據,後建適配器,最後綁定視圖」是 Android 列表開發的鐵律。ArrayAdapter.add() 適用於運行時動態增刪,初始化階段請使用構造函數注入列表。

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