Как обновить ListView из AsyncTask? - PullRequest
1 голос
/ 16 ноября 2011

Я загружаю изображения с помощью 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();
}
}

Ответы [ 3 ]

2 голосов
/ 16 ноября 2011

Причина, по которой он не работает, заключается в том, что notifyDataSetChanged() только сообщает ListView, что данные в адаптере изменились.Поскольку эти данные не изменились (потому что вы больше не обращались к базе данных), ListView не будет показывать никаких обновлений.Вам необходимо снова выполнить запрос и обновить данные в адаптере, , затем , вызов notifyDatasetChanged().

1 голос
/ 16 ноября 2011

Почему бы не использовать ContentProvider.

С помощью ContentProvider вы можете обновить таблицу с помощью метода notifyChange (uri)

Учебник для этого здесь http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/

0 голосов
/ 25 сентября 2012

Я думаю, вы можете обновить ImageView в ListView в методе onPostExecute(). Вот как я выполнил нечто похожее на то, что вы делаете: Многопоточность для производительности

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...