这是我的代码的一部分,我使用异步任务从数据库中搜索并使用简单的适配器填充listview。
protected String doInBackground(String... arg0)
{
Cursor TROWS;
ArrayList<HashMap<String, String>> LstViw_VItem=new ArrayList<HashMap<String,String>>();
HashMap<String, String>VMap;
try
{
DBH.openDataBase();
SQLiteDatabase SQLITE=SQLiteDatabase.openDatabase(myPath, null, Context.MODE_PRIVATE);
if (TxtVerminSearch.getText().length()==0)
{
TROWS=SQLITE.rawQuery("select id,vermin_name from pistachio_vermins", null);
}
else
{
TROWS=SQLITE.rawQuery("select id,vermin_name from pistachio_vermins where vermin_name like '%"+TxtVerminSearch.getText()+"%'", null);
}
if (TROWS.moveToFirst())
{
do
{
String VID =TROWS.getString(0);
String VName =TROWS.getString(1);
VMap=new HashMap<String, String>();
VMap.put("VerminID", VID);
VMap.put("VerminName", VName);
LstViw_VItem.add(VMap);
}
while (TROWS.moveToNext());
SimpleAdapter SA=new SimpleAdapter(getApplicationContext(), LstViw_VItem, R.layout.xvermin_items, new String[]{"VerminID","VerminName"}, new int[]{R.id.mainmenu_items__lbl_vermin_id,R.id.mainmenu_items__lbl_vermins});
LstViwVerminItems.setAdapter(SA);
LstViwVerminItems.setEnabled(true);
}
else
{
VMap=new HashMap<String, String>();
VMap.put("VerminID", "-1");
VMap.put("VerminName", "nothing found");
VMap.put("ImgViw",String.valueOf(R.drawable.warning_48));
LstViw_VItem.add(VMap);
SimpleAdapter SA=new SimpleAdapter(getApplicationContext(), LstViw_VItem, R.layout.xvermin_items, new String[]{"VerminID","VerminName","ImgViw"}, new int[]{R.id.mainmenu_items__lbl_vermin_id,R.id.mainmenu_items__lbl_vermins,R.id.mainmenu_items__ImgViw});
LstViwVerminItems.setAdapter(SA);
LstViwVerminItems.setEnabled(false);
}
}
catch (Exception e)
{
final String errString;
errString=e.getMessage();
Log.d("ERR: ", errString);
runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(JAct_Vermins.this, errString, Toast.LENGTH_LONG).show();
}
});
}
return null;
}
每件事都很好但是当搜索结果为空时我会给出这样的错误:
只有创建视图层次结构的原始线程才能触及其视图。
问题发生在这一行
VMap.put("ImgViw",String.valueOf(R.drawable.warning_48));
为此,我使用runOnUiThread函数来访问ui。但我现在不能这样做因为我不能宣布VMap为最终
答案 0 :(得分:0)
您应该使用onPostExecute方法在UI上显示结果。了解有关AsyncTask的更多信息。你不应该在doInBackground方法处理UI。
答案 1 :(得分:0)
尝试在HashMap<String, String> VMap;
之外声明doInBackgound()
并使用runOnUiThread()
。如果它仍然不起作用,请尝试创建一个Handler并将hashmap key-val作为Message传递。
注意:在VMap
doInBackground()
变量
示例:
HashMap<String, String> VMap;
@Override
protected String doInBackground(String... params) {
Cursor TROWS;
ArrayList<HashMap<String, String>> LstViw_VItem = new ArrayList<HashMap<String, String>>();
try {
DBH.openDataBase();
SQLiteDatabase SQLITE = SQLiteDatabase.openDatabase(myPath, null,
Context.MODE_PRIVATE);
if (TxtVerminSearch.getText().length() == 0) {
TROWS = SQLITE.rawQuery("select id,vermin_name from pistachio_vermins", null);
} else {
TROWS = SQLITE.rawQuery(
"select id,vermin_name from pistachio_vermins where vermin_name like '%"
+ TxtVerminSearch.getText() + "%'", null);
}
if (TROWS.moveToFirst()) {
do {
String VID = TROWS.getString(0);
String VName = TROWS.getString(1);
VMap = new HashMap<String, String>();
VMap.put("VerminID", VID);
VMap.put("VerminName", VName);
LstViw_VItem.add(VMap);
} while (TROWS.moveToNext());
SimpleAdapter SA = new SimpleAdapter(getApplicationContext(), LstViw_VItem,
R.layout.xvermin_items, new String[] { "VerminID", "VerminName" },
new int[] { R.id.mainmenu_items__lbl_vermin_id,
R.id.mainmenu_items__lbl_vermins });
LstViwVerminItems.setAdapter(SA);
LstViwVerminItems.setEnabled(true);
} else {
VMap = new HashMap<String, String>();
VMap.put("VerminID", "-1");
VMap.put("VerminName", "nothing found");
mHandler.sendEmptyMessage(0);
LstViw_VItem.add(VMap);
SimpleAdapter SA = new SimpleAdapter(getApplicationContext(), LstViw_VItem,
R.layout.xvermin_items, new String[] { "VerminID", "VerminName",
"ImgViw" }, new int[] { R.id.mainmenu_items__lbl_vermin_id,
R.id.mainmenu_items__lbl_vermins, R.id.mainmenu_items__ImgViw });
LstViwVerminItems.setAdapter(SA);
LstViwVerminItems.setEnabled(false);
}
} catch (Exception e) {
final String errString;
errString = e.getMessage();
Log.d("ERR: ", errString);
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(JAct_Vermins.this, errString, Toast.LENGTH_LONG).show();
}
});
}
return null;
}
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
VMap.put("ImgViw", String.valueOf(R.drawable.warning_48));
super.handleMessage(msg);
}
};
希望它有所帮助!
答案 2 :(得分:0)
您正在尝试从背景更新listview,这是错误的。 为了更新ui android提供post执行方法,你应该在postexecute方法中编写更新listview的代码。供您参考,您可以看到此链接http://www.compiletimeerror.com/2013/01/why-and-how-to-use-asynctask.html
答案 3 :(得分:0)
函数doInBackgound() - 无法从ui tread调用函数
使用runOnUiThread()或onPostExecute()