无法从AsyncThread设置的ListView适配器 [英] Can't set ListView Adapter from AsyncThread

查看:92
本文介绍了无法从AsyncThread设置的ListView适配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了一个的ListView 我的活动,它需要一段时间才能从一个SQLite数据库加载,所以我想表现出 ProgressDialog 给用户,让他们知道什么是加载。我试图在一个单独的线程上运行的任务,但我得到一个 CalledFromWrongThreadException 。这是我的主活动 code:

  @覆盖
公共无效的onCreate(包savedInstanceState)
{
    尝试
    {
        super.onCreate(savedInstanceState);

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

        //设置窗口标题。
        最后的TextView标题=(TextView中)findViewById(R.id.customTitle);
        如果(标题!= NULL)
            title.setText(开放式问题);

        //调用异步任务在后台运行。
        新LoadIssuesTask()执行();
    }
    赶上(例外五)
    {
        Errors.LogError(E);
    }
}
 

而LoadIssuesTask code:

 私有类LoadIssuesTask扩展的AsyncTask<虚空,虚空,光标> {

    ProgressDialog pdDialog = NULL;
   在preExecute保护无效()
   {
       尝试
       {
           pdDialog =新ProgressDialog(OpenIssues.this);
           pdDialog.setMessage(加载问题和活动,请稍候...);
           pdDialog.show();
       }
       赶上(例外五)
       {
           Errors.LogError(E);
       }
   }

   @覆盖
   受保护的光标doInBackground(空... PARAMS){
       LoadIssues();
       返回null;
   }

   @覆盖
   保护无效onPostExecute(光标C){
       pdDialog.dismiss();
       pdDialog = NULL;
   }
 }
 

而LoadIssues code:

 私人无效LoadIssues(){
    //设置问题的列表视图。
    ListView控件lvIssues =(ListView控件)findViewById(R.id.lvIssues);
    lvIssues.setOnItemClickListener(viewIssuesListener);

    IssueCreator =新IssueInfoCreator(这一点,的Integer.parseInt(应用程序preferences.mDBVersion));
    IssueCreator.open();
    lvIssues.setAdapter(新IssueInfoAdapter(此,IssueCreator.queryAll()));
    IssueCreator.close();
}
 

构造IssueInfoAdapter:

 公共IssueInfoAdapter(上下文C,名单,其中,IssueInfo>列表){
    mListIssueInfo =清单;

    //创建布局充气。
    mInflater = LayoutInflater.from(C);
}
 

它扔在.setAdapter方法​​中 LoadIssues错误()。 错误:

  10月3号至12号:41:23.174:E / AndroidRuntime(11379):android.view.ViewRootImpl $ CalledFromWrongThreadException:产生的原因:
只有创建一个视图层次可以触摸其观点原来的线程。
 

解决方案

您正在试图访问一个不主运行 doInBackground 法的意见 UI 线程。你必须设置您的适配器的方法 onPostExecute UI 线程上运行:

  @覆盖
   保护无效onPostExecute(名单< IsueInfo>项目){
       pdDialog.dismiss();
       ListView控件lvIssues =(ListView控件)findViewById(R.id.lvIssues);
       lvIssues.setOnItemClickListener(viewIssuesListener);
       lvIssues.setAdapter(新IssueInfoAdapter(这一点,项目));
   }
 

和您的 doInBackground 方法:

  @覆盖
       受保护的名单,其中,IssueInfo> doInBackground(空... PARAMS){
            IssueCreator =新IssueInfoCreator(这一点,的Integer.parseInt(应用程序preferences.mDBVersion));
        IssueCreator.open();

        IssueCreator.close();
        返回IssueCreator.queryAll();

   }
 

此外,您的AsyncTask的应该是:

 私有类LoadIssuesTask扩展的AsyncTask<虚空,虚空,名单,其中,IssueInfo>>
 

I'm using a ListView on my Activity and it takes a while to load from a SQLite DB, so I wanted to show a ProgressDialog to the user to let them know something is loading. I tried to run the task on a separate thread but I'm getting a CalledFromWrongThreadException. Here's my main Activity code:

@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);
    }
}

And the LoadIssuesTask code:

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;
   }
 }

And the LoadIssues code:

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();
}

Constructor for IssueInfoAdapter:

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

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

It's throwing the error on the .setAdapter method inside LoadIssues(). ERROR:

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.

解决方案

You're trying to access the views in the doInBackground method that doesn't run on the main UI thread. You'll have to set your adapter in the method onPostExecute that runs on the UI thread:

@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));
   }

and in your doInBackground method:

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

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

   }

Also your AsyncTask should be:

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

这篇关于无法从AsyncThread设置的ListView适配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆