【发布时间】:2011-11-16 15:21:12
【问题描述】:
我正在使用 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();
}
}
【问题讨论】:
-
1.不要将图像存储在 DB 2 中。使用 Ihttp://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012
-
为什么不能用DB来存储图片?据我所知,与文件系统相比,它的工作速度足够快。
-
您的数据库将变得不必要......在这种情况下,Android 上的良好做法是只存储一个路径(在 android 文件系统(缓存/外部/内部存储)上)以在 db 中归档......无论如何...您的数据库是静态的(与 apk 一起分发)还是您下载它?
-
你为什么不把图片放到drawable文件夹中并使用重写的SimpleCursorAdapter方法
@Override public void setViewImage(ImageView v, String value) { Context ctx = v.getContext(); v.setImageResource(ctx .getResources().getIdentifier(value, "drawable", ctx .getPackageName())); }和在db中只存储这个drawable的名称? -
图片存放在文件夹/db/sd/drawable中是没有问题的。之后我只想更新 ListView。
标签: android database listview android-asynctask