1

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();
}
}
Sviatoslav
  • 1,301
  • 2
  • 17
  • 42
  • 1. don't store images in DB 2. use Ihttp://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012 – Selvin Nov 16 '11 at 15:41
  • Why does I must not to use DB for storing images? As I know it is working enough quickly in comparison with file system. – Sviatoslav Nov 16 '11 at 16:34
  • your db will grow unnecessary ... good practice on android in such cases is to store only a path(on android filesystem(cache/external/internal storage)) to file in db... anyway ... is your db static(distrbuted with apk) or you download it ? – Selvin Nov 16 '11 at 16:52
  • why don't you put images to drawable folder and use overriden SimpleCursorAdapter with method `@Override public void setViewImage(ImageView v, String value) { Context ctx = v.getContext(); v.setImageResource(ctx .getResources().getIdentifier(value, "drawable", ctx .getPackageName())); }` and in db just store name of this drawable ? – Selvin Nov 16 '11 at 17:10
  • It's not a problem to store images in folder/db/sd/drawable. I want simply to update **ListView** after that. – Sviatoslav Nov 16 '11 at 17:15
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5059/discussion-between-selvin-and-svyatoslav) – Selvin Nov 16 '11 at 17:15

3 Answers3

2

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 call notifyDatasetChanged().

dmon
  • 30,048
  • 8
  • 87
  • 96
  • What do you mean by "update the data in the adapter"? What does I must to write in **onProgressUpdate** method? – Sviatoslav Nov 16 '11 at 16:26
1

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/

Mathieu Hausherr
  • 3,485
  • 23
  • 30
0

I think you may want to update the ImageView in a ListView in the onPostExecute() method. This is how I accomplished something similar to what you are doing : Multithreading For Performance

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Etienne Lawlor
  • 6,817
  • 18
  • 77
  • 89