无法从AsyncThread设置的ListView适配器 [英] Can't set ListView Adapter from AsyncThread
问题描述
我使用了一个的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屋!