无法从AsyncThread设置ListView适配器

Rob*_*ert 1 android

我正在使用ListView我的Activity一个,从SQLite DB加载需要一段时间,所以我想向ProgressDialog用户显示一个让他们知道正在加载的东西.我试图在一个单独的线程上运行任务,但我得到了一个CalledFromWrongThreadException.这是我的主要Activity代码:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

和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;
   }
 }
Run Code Online (Sandbox Code Playgroud)

和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();
}
Run Code Online (Sandbox Code Playgroud)

IssueInfoAdapter的构造函数:

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

    //create layout inflater.
    mInflater = LayoutInflater.from(c);
}
Run Code Online (Sandbox Code Playgroud)

它在内部的.setAdapter方法上抛出错误LoadIssues().错误:

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.
Run Code Online (Sandbox Code Playgroud)

Luk*_*rog 10

您正在尝试访问doInBackground未在主UI线程上运行的方法中的视图.您必须onPostExecuteUI线程上运行的方法中设置适配器:

@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));
   }
Run Code Online (Sandbox Code Playgroud)

在你的doInBackground方法中:

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

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

   }
Run Code Online (Sandbox Code Playgroud)

您的AsyncTask也应该是:

private class LoadIssuesTask extends AsyncTask<Void, Void, List<IssueInfo>>
Run Code Online (Sandbox Code Playgroud)