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

Android Handler 執行緒中更新 UI 導致 ArrayAdapter 建構失敗

     編輯:程式設計綜合問答

錯誤程式碼片段

class UpdateTask implements Runnable {
    @Override
    public void run() {
        // 非 UI 執行緒
        setContentView(R.layout.activity_messages); // 錯誤:只能在 UI 執行緒呼叫
        ListView lm = (ListView) findViewById(R.id.listView1);
        ArrayAdapter<String> adpt = new ArrayAdapter<String>(this, 
            android.R.layout.simple_list_item_1, lst); // 錯誤:this 非 Context
        lm.setAdapter(adpt);
        handler.postDelayed(this, 500);
    }
}

兩大核心問題

  1. Context 傳遞錯誤:ArrayAdapter 建構子第一個參數需為 Context,匿名內部類別中的 this 指向 Runnable 實例,而非 Activity。應改為 YourActivity.this 或 getApplicationContext()。
  2. 非 UI 執行緒操作 View:run() 在背景執行緒執行,直接呼叫 setContentView、findViewById、setAdapter 會拋出 CalledFromWrongThreadException。

正確做法

class UpdateTask implements Runnable {
    @Override
    public void run() {
        // 1. 背景執行緒只做資料查詢
        final List<String> data = cs.GetMessage(id);
        
        // 2. 切回 UI 執行緒更新介面
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ListView lm = (ListView) findViewById(R.id.listView1);
                ArrayAdapter<String> adpt = new ArrayAdapter<>(
                    MainActivity.this, 
                    android.R.layout.simple_list_item_1, 
                    data);
                lm.setAdapter(adpt);
            }
        });
        
        // 3. 排程下一次輪詢
        handler.postDelayed(this, 500);
    }
}

關鍵點總結

  • 資料查詢(網路、資料庫)放在背景執行緒。
  • 所有 View 操作必須在 UI 執行緒(runOnUiThread、Handler.post、AsyncTask.onPostExecute)。
  • 建構 ArrayAdapter 時傳入 Activity.this 或 getContext()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved