我使用 AsyncTask 加载图片,为了更新ListView,我正在使用 notifyDataSetChanged()方法。
但 notifyDataSetChanged()不会更改ListView onProgressUpdate()中的任何内容。 我不想使用 cursor.requery ,因为它是不推荐使用的方法。
为什么 notifyDataSetChanged()对我不起作用?
public class News extends BasicActivity implements OnItemClickListener{
private SQLiteDatabase db = null;
private ListView lvNews;
private TaskImgSm taskImgSm = null;
private NewsListAdapter adapter;
private Cursor cur;
boolean pause = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news);
db = SQLiteDatabase.openDatabase(((MyApp) getApplication()).getDbPath(), null, SQLiteDatabase.OPEN_READWRITE);
lvNews = (ListView) findViewById(R.id.list_news);
lvNews.setOnItemClickListener(this);
listFilling();
if (taskImgSm != null && taskImgSm.getStatus() != AsyncTask.Status.FINISHED) taskImgSm.cancel(true);
taskImgSm = new TaskImgSm();
taskImgSm.execute();
}
private void listFilling() {
cur = db.query("news", new String[] { "_id", "id_news", "title", "date", "img_url", "img_sm" }, null, null, null, null, null);
startManagingCursor(cur);
adapter = new NewsListAdapter(this, cur, db);
lvNews.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
class TaskImgSm extends AsyncTask<Void, String, Void> {
Cursor curs;
@Override
protected void onPreExecute() {
super.onPreExecute();
curs = db.query("news", new String[] { "_id", "id_news", "img_url", "img_sm" }, null, null, null, null, null);
startManagingCursor(curs);
}
@Override
protected Void doInBackground(Void... unused) {
curs.moveToFirst();
while (curs.isAfterLast() == false) {
if (curs.getBlob(curs.getColumnIndex("img_sm")) == null) {
String imgUrl = curs.getString(curs.getColumnIndex("img_url"));
String idNews = curs.getString(curs.getColumnIndex("id_news"));
updateImg(imgUrl, idNews, "img_sm");
publishProgress();
}
curs.moveToNext();
}
return (null);
}
private void updateImg(String img_URL, String whereId, String imgColumn) {
try {
DefaultHttpClient mHttpClient = new DefaultHttpClient();
HttpGet mHttpGet = new HttpGet();
mHttpGet.setURI(new URI(img_URL));
HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
if (mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = mHttpResponse.getEntity();
if (entity != null) {
// insert to database
ContentValues values = new ContentValues();
values.put(imgColumn, EntityUtils.toByteArray(entity));
db.update("news", values, "id_news=" + whereId, null);
}
}
} catch (URISyntaxException e) {e.printStackTrace();
} catch (ClientProtocolException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();}
}
@Override
protected void onProgressUpdate(String... item) {
if (pause == false) {
adapter.notifyDataSetChanged();
}
}
@Override
protected void onPostExecute(Void unused) {}
}
@Override
protected void onPause() {
pause = true;
super.onPause();
}
@Override
protected void onResume() {
pause = false;
adapter.notifyDataSetChanged();
super.onResume();
}
@Override
protected void onDestroy() {
if (taskImgSm != null && taskImgSm.getStatus() != AsyncTask.Status.FINISHED) taskImgSm.cancel(true);
super.onDestroy();
}
}
答案 0 :(得分:2)
它不起作用的原因是因为notifyDataSetChanged()
仅告诉ListView适配器中的数据已更改。由于该数据未更改(因为您尚未再次查询数据库),因此ListView不会显示任何更新。您需要再次执行查询并更新适配器中的数据,然后调用notifyDatasetChanged()
。
答案 1 :(得分:1)
为什么不使用ContentProvider。
使用ContentProvider,您可以使用notifyChange(uri)方法
更新表此处的教程http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/
答案 2 :(得分:0)
我认为您可能希望更新ImageView
方法中ListView
中的onPostExecute()
。这就是我完成类似于你正在做的事情的方式:Multithreading For Performance