2012-03-12 57 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