2012-03-12 83 views
1

我在我的Activity上使用ListView,並且需要一段時間才能從SQLite數據庫加載,所以我想向用戶顯示一個ProgressDialog以讓他們知道正在加載的內容。我試圖在一個單獨的線程上運行任務,但我得到一個CalledFromWrongThreadException。這是我的主要Activity代碼:無法從AsyncThread設置ListView適配器

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    try 
    { 
     super.onCreate(savedInstanceState); 

     requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
     setContentView(R.layout.open_issues); 
     getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title); 

     //Set Window title. 
     final TextView title = (TextView) findViewById(R.id.customTitle); 
     if (title != null) 
      title.setText("Open Issues"); 

     //Call Async Task to run in the background. 
     new LoadIssuesTask().execute(); 
    } 
    catch (Exception e) 
    { 
     Errors.LogError(e); 
    } 
} 

而且LoadIssuesTask代碼:

private class LoadIssuesTask extends AsyncTask<Void, Void, Cursor> { 

    ProgressDialog pdDialog = null; 
    protected void onPreExecute() 
    { 
     try 
     { 
      pdDialog = new ProgressDialog(OpenIssues.this); 
      pdDialog.setMessage("Loading Issues and Activities, please wait..."); 
      pdDialog.show(); 
     } 
     catch (Exception e) 
     { 
      Errors.LogError(e); 
     } 
    } 

    @Override 
    protected Cursor doInBackground(Void... params) { 
     LoadIssues(); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Cursor c) { 
     pdDialog.dismiss(); 
     pdDialog = null; 
    } 
} 

而且LoadIssues代碼:

private void LoadIssues(){ 
    //Set listview of Issues. 
    ListView lvIssues = (ListView)findViewById(R.id.lvIssues); 
    lvIssues.setOnItemClickListener(viewIssuesListener); 

    IssueCreator = new IssueInfoCreator(this, Integer.parseInt(AppPreferences.mDBVersion)); 
    IssueCreator.open(); 
    lvIssues.setAdapter(new IssueInfoAdapter(this, IssueCreator.queryAll()));   
    IssueCreator.close(); 
} 

構造IssueInfoAdapter:

public IssueInfoAdapter(Context c, List<IssueInfo> list){ 
    mListIssueInfo = list; 

    //create layout inflater. 
    mInflater = LayoutInflater.from(c); 
} 

這是THR由於LoadIssues()中.setAdapter方法的錯誤。 錯誤:

03-12 10:41:23.174: E/AndroidRuntime(11379): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views. 

回答

9

您正試圖訪問doInBackground方法中的視圖,該方法不會在主線程上運行。你必須設置你的適配器上的UI線程上運行的方法onPostExecute

@Override 
    protected void onPostExecute(List<IsueInfo> items) { 
     pdDialog.dismiss(); 
     ListView lvIssues = (ListView)findViewById(R.id.lvIssues); 
     lvIssues.setOnItemClickListener(viewIssuesListener); 
     lvIssues.setAdapter(new IssueInfoAdapter(this, items)); 
    } 

,並在您doInBackground方法:

@Override 
     protected List<IssueInfo> doInBackground(Void... params) { 
      IssueCreator = new IssueInfoCreator(this, Integer.parseInt(AppPreferences.mDBVersion)); 
     IssueCreator.open(); 

     IssueCreator.close(); 
     return IssueCreator.queryAll(); 

    } 

而且您的AsyncTask應該是:

private class LoadIssuesTask extends AsyncTask<Void, Void, List<IssueInfo>> 
-3

private void LoadIssues方法調用handler.setMessage(0),並創建一個private Handler實例調用setAdapter方法

使用Handler而不是Asynctask