如何从AsyncTask更新ListView?
我正在使用 AsyncTask 加载图像,并使用 notifyDataSetChanged() 方法更新 ListView。
但是 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();
}
}
I am loading images by using AsyncTask and for updating ListView I am using notifyDataSetChanged() method.
But notifyDataSetChanged() doesn't change anything in the ListView onProgressUpdate().
I don't want to use cursor.requery because it is deprecated method.
Why notifyDataSetChanged() is not working for me?
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它不起作用的原因是
notifyDataSetChanged()
仅告诉 ListView 适配器中的数据已更改。由于该数据没有更改(因为您没有再次查询数据库),因此 ListView 将不会显示任何更新。您需要再次执行查询并更新适配器中的数据,然后调用notifyDatasetChanged()
。The reason it's not working is because
notifyDataSetChanged()
only tells the ListView that the data in the adapter has changed. Since that data hasn't changed (because you haven't queried the database again), then the ListView won't show any updates. You need to execute the query again and update the data in the adapter, then callnotifyDatasetChanged()
.为什么不使用 ContentProvider。
使用ContentProvider,您可以使用notifyChange(uri)方法更新您的表
教程在这里 http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/
Why don't use a ContentProvider.
With a ContentProvider you can update your table with the notifyChange(uri) method
Tutorial for that here http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/
我想您可能想在
onPostExecute()
方法中更新ListView
中的ImageView
。这就是我完成与您正在做的类似的事情的方法: Multithreading For性能I think you may want to update the
ImageView
in aListView
in theonPostExecute()
method. This is how I accomplished something similar to what you are doing : Multithreading For Performance