Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何从AsyncTask更新ListView?_Android_Database_Listview_Android Asynctask - Fatal编程技术网

Android 如何从AsyncTask更新ListView?

Android 如何从AsyncTask更新ListView?,android,database,listview,android-asynctask,Android,Database,Listview,Android Asynctask,我使用AsyncTask加载图像,对于更新ListView,我使用notifyDataSetChanged()方法 但是notifyDataSetChanged()不会更改ListView onProgressUpdate()中的任何内容。 我不想使用cursor.requery,因为它是不推荐使用的方法 为什么notifyDataSetChanged()不适合我 public class News extends BasicActivity implements OnItemClickList

我使用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();
}
}
公共类新闻扩展了基本活动,实现了McClickListener{
私有SQLiteDatabase db=null;
私有列表视图;
私有任务imgsm TaskImgSm=null;
私有新闻列表适配器;
私有游标cur;
布尔暂停=假;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.news);
db=SQLiteDatabase.openDatabase(((MyApp)getApplication()).getDbPath(),null,SQLiteDatabase.OPEN\u READWRITE);
lvNews=(ListView)findViewById(R.id.list\u news);
lvNews.setOnItemClickListener(this);
列表填充();
如果(taskImgSm!=null&&taskImgSm.getStatus()!=AsyncTask.Status.FINISHED)taskImgSm.cancel(true);
taskImgSm=新任务imgsm();
taskImgSm.execute();
}
私人空置列表填充(){
cur=db.query(“news”,新字符串[]{“\u id”,“id\u news”,“title”,“date”,“img\u url”,“img\u sm”},null,null,null,null);
开始管理光标(cur);
adapter=新的NewsListAdapter(this,cur,db);
lvNews.setAdapter(适配器);
adapter.notifyDataSetChanged();
}
类TaskImgSm扩展了异步任务{
光标光标;
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
curs=db.query(“news”,新字符串[]{“\u id”,“id\u news”,“img\u url”,“img\u sm”},null,null,null,null);
开始管理光标(curs);
}
@凌驾
受保护的空位背景(空位…未使用){
curs.moveToFirst();
while(curs.isAfterLast()==false){
if(curs.getBlob(curs.getColumnIndex(“img_sm”))==null){
字符串imgUrl=curs.getString(curs.getColumnIndex(“img_url”);
String idNews=curs.getString(curs.getColumnIndex(“id_news”));
updateImg(imgUrl,idNews,“img_sm”);
出版进度();
}
curs.moveToNext();
}           
返回(空);
}
私有void updateImg(字符串img_URL、字符串whereId、字符串imgColumn){
试一试{
DefaultHttpClient mHttpClient=新的DefaultHttpClient();
HttpGet mHttpGet=新的HttpGet();
setURI(新URI(img_URL));
HttpResponse mHttpResponse=mHttpClient.execute(mHttpGet);
if(mHttpResponse.getStatusLine().getStatusCode()==HttpStatus.SC\u OK){
HttpEntity entity=mHttpResponse.getEntity();
如果(实体!=null){
//插入到数据库
ContentValues=新的ContentValues();
value.put(imgColumn,EntityUtils.toByteArray(entity));
db.update(“news”,值,“id_news=“+whereId,null”);
}
}
}catch(URISyntaxException e){e.printStackTrace();
}catch(ClientProtocolException e){e.printStackTrace();
}catch(IOE异常){e.printStackTrace();}
}
@凌驾
受保护的void onProgressUpdate(字符串…项){
如果(暂停==false){
adapter.notifyDataSetChanged();
}
}
@凌驾
受保护的void onPostExecute(void unused){}
}
@凌驾
受保护的void onPause(){
暂停=正确;
super.onPause();
}
@凌驾
受保护的void onResume(){
暂停=错误;
adapter.notifyDataSetChanged();
super.onResume();
}
@凌驾
受保护的空onDestroy(){
如果(taskImgSm!=null&&taskImgSm.getStatus()!=AsyncTask.Status.FINISHED)taskImgSm.cancel(true);
super.ondestory();
}
}

为什么不使用ContentProvider呢

使用ContentProvider,您可以使用notifyChange(uri)方法更新表


此处的教程

它不工作的原因是因为
notifyDataSetChanged()
只告诉ListView适配器中的数据已更改。由于数据没有更改(因为您没有再次查询数据库),因此ListView不会显示任何更新。您需要再次执行查询并更新适配器中的数据,然后调用
notifyDatasetChanged()

我想您可能需要更新
onPostExecute()方法中
ListView
中的
ImageView
。这就是我完成类似于您所做的事情的方式:

1。不要将图像存储在DB 2中。使用我http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012#3068012Why 我必须不使用DB来存储图像吗?据我所知,与文件系统相比,它的运行速度足够快。您的数据库将变得不必要。。。在这种情况下,android上的良好实践是只存储一个路径(在android文件系统(缓存/外部/内部存储)到db中的文件。。。无论如何您的db是静态的(由apk分发)还是下载的?为什么不将图像放到drawable文件夹中,并使用重写的SimpleCursorAdapter with method
@Override public void setViewImage(ImageView v,String value){Context ctx=v.getContext();v.setImageResource(ctx.getResources().getIdentifier(value,“drawable”,ctx.getPackageName())}
在db中只存储此可绘制文件的名称?在/db/sd/drawable文件夹中存储图像不是问题。我只想在那之后更新ListView。你说的“更新适配器中的数据”是什么意思?我必须在onProgressUpdate方法中编写什么?