2011-11-16 62 views
1

我正在通过使用AsyncTask和更新ListView我正在使用notifyDataSetChanged()方法加载图像。如何从AsyncTask更新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(); 
} 
} 
+0

1.不要在DB中存储图像2.使用Ihttp://stackoverflow.com/questions/541966/android-how-do-i-do -a-lazy-load-of-images-in-listview/3068012#3068012 – Selvin

+0

为什么我不能用DB来存储图像?据我所知,与文件系统相比,它的工作速度足够快。 – Sviatoslav

+0

你的数据库将增加不必要的...在这种情况下,在Android上的良好做法是只存储一个路径(在Android文件系统(缓存/外部/内部存储))到文件中的数据库...无论如何...是你的数据库静态(与apk分发)或者你下载它? – Selvin

回答

2

它不工作的原因是因为notifyDataSetChanged()只告诉ListView控件,在数据适配器已更改。由于该数据没有改变(因为你没有再次查询数据库),那么ListView将不会显示任何更新。您需要再次执行查询并更新适配器中的数据,,然后请致电notifyDatasetChanged()

+0

“更新适配器中的数据”是什么意思?我必须在** onProgressUpdate **方法中写入什么? – Sviatoslav