定期更新ListView

时间:2014-02-17 10:03:13

标签: android android-listview android-sqlite

在我的代码中,我希望在每 10秒后定期更新ListView 。由于ListView是自定义的,ListView中的数据是从数据库填充的,因此我需要定期刷新ListView,以便数据库中的任何更改都可以反映在ListView中。我尝试使用Handler概念,但它没有帮助我。以下是我的代码。需要做什么?

 public class GetFriendDeviceId extends ListActivity {

        String data = "";

        String title;


        ListView list;
        CustomDeviceId adapter;
        ArrayList<String> useridarr;
        ArrayList<String> namearr;
        ArrayList<String> regidarr;

        ArrayList<String> statusarr;
        String id;

        String userid, name, regid;

        private static final String USERID = "user_id";
        private static final String NAME = "user_name";
        private static final String REGID = "regId";

        DBController contoller = new DBController(this);

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.getfriend_deviceid);

            useridarr = new ArrayList<String>();
            namearr = new ArrayList<String>();
            regidarr = new ArrayList<String>();
            statusarr = new ArrayList<String>();

            // get user_id using sharedpreference
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
            id = preferences.getString("ID", "");

            new GetContent().execute();

        }

        // asynctask to get content for selected title
        public class GetContent extends AsyncTask<Void, Void, Void>
        {
             ProgressDialog pdLoading = new ProgressDialog(GetFriendDeviceId.this);

            @Override
            protected void onPreExecute() {
                super.onPreExecute();

                    useridarr.clear();
                namearr.clear();
                regidarr.clear();
                statusarr.clear();

                pdLoading.setMessage("\tPlease wait...");
            pdLoading.show();
            }

            @Override
            protected Void doInBackground(Void... params) {
                final GetDeviceId getdb = new GetDeviceId();
                new Thread(new Runnable() {
                    public void run() {
                        data = getdb.getDataFromDB(id);
                        System.out.println(data);

                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                ArrayList<User_DeviceId> users = parseJSON(data);
                                addData(users);                     
                            }
                        });

                    }
                }).start();

                return null;

            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);

                pdLoading.dismiss();

            }
        }



        public ArrayList<User_DeviceId> parseJSON(String result) {
            ArrayList<User_DeviceId> users = new ArrayList<User_DeviceId>();

            try
            {
                JSONArray jArray = new JSONArray(result);

                for (int i = 0; i < jArray.length(); i++) 
                {
                    JSONObject json_data = jArray.getJSONObject(i);
                    User_DeviceId user = new User_DeviceId();

                    user.setUser_id(json_data.getString(USERID));
                    user.setUser_name(json_data.getString(NAME));
                    user.setRegId(json_data.getString(REGID));
                    users.add(user);

                }


            } catch (JSONException e) {
                Log.e("log_tag", "Error parsing data " + e.toString());  
            }
            return users;
        }


        @SuppressWarnings({ "rawtypes" })
        public void addData(ArrayList<User_DeviceId> users) {

            for (Iterator i = users.iterator(); i.hasNext();) {

                User_DeviceId p = (User_DeviceId) i.next();

                useridarr.add(p.getUser_id());
                namearr.add(p.getUser_name());
                regidarr.add(p.getRegId());

            }


            DBController.statusArray = statusarr;
        contoller.getStatus(id, useridarr, 0);

            adapter = new CustomDeviceId(GetFriendDeviceId.this, namearr, useridarr, statusarr);
            list.setAdapter(adapter);

        }

我试过这段代码

final Handler handler_new = new Handler();
        handler_new.postDelayed( new Runnable() {
        @Override
            public void run() {

                DBController.statusArray = MainActivity.result;
                contoller.Status("100003818200590", "100007144268382", 0);
                MainActivity.adapter.notifyDataSetChanged();
                handler_new.postDelayed( this, 1000);

            }
        }, 1000);

但是没有用......

3 个答案:

答案 0 :(得分:2)

我只是编辑您的代码希望这可以帮助您

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.ListView;

public class GetFriendDeviceId extends ListActivity {

    String data = "";

    String title;

    ListView list;
    CustomDeviceId adapter;
    ArrayList<String> useridarr;
    ArrayList<String> namearr;
    ArrayList<String> regidarr;

    ArrayList<String> statusarr;
    String id;

    String userid, name, regid;

    private static final String USERID = "user_id";
    private static final String NAME = "user_name";
    private static final String REGID = "regId";

    DBController contoller;

    Timer timer;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.getfriend_deviceid);
        contoller = new DBController(this);
        useridarr = new ArrayList<String>();
        namearr = new ArrayList<String>();
        regidarr = new ArrayList<String>();
        statusarr = new ArrayList<String>();

        // get user_id using sharedpreference
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        id = preferences.getString("ID", "");

        timer = new Timer();

        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        new GetContent().execute();
                    }
                });

            }
        }, 0, 10000);

    }

    // asynctask to get content for selected title
    public class GetContent extends AsyncTask<Void, Void, ArrayList<User_DeviceId>> {
        ProgressDialog pdLoading = new ProgressDialog(GetFriendDeviceId.this);

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            useridarr.clear();
            namearr.clear();
            regidarr.clear();
            statusarr.clear();
            pdLoading.setMessage("\tPlease wait...");
            pdLoading.show();
        }

        @Override
        protected ArrayList<User_DeviceId> doInBackground(Void... params) {
            final GetDeviceId getdb = new GetDeviceId();
            data = getdb.getDataFromDB(id);
            ArrayList<User_DeviceId> users = parseJSON(data);

            return users;

        }

        @Override
        protected void onPostExecute(ArrayList<User_DeviceId> result) {
            super.onPostExecute(result);
            addData(result);
            pdLoading.dismiss();

        }
    }

    public ArrayList<User_DeviceId> parseJSON(String result) {
        ArrayList<User_DeviceId> users = new ArrayList<User_DeviceId>();

        try {
            JSONArray jArray = new JSONArray(result);

            for (int i = 0; i < jArray.length(); i++) {
                JSONObject json_data = jArray.getJSONObject(i);
                User_DeviceId user = new User_DeviceId();

                user.setUser_id(json_data.getString(USERID));
                user.setUser_name(json_data.getString(NAME));
                user.setRegId(json_data.getString(REGID));
                users.add(user);

            }

        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
        return users;
    }

    @SuppressWarnings({ "rawtypes" })
    public void addData(ArrayList<User_DeviceId> users) {

        for (Iterator i = users.iterator(); i.hasNext();) {

            User_DeviceId p = (User_DeviceId) i.next();

            useridarr.add(p.getUser_id());
            namearr.add(p.getUser_name());
            regidarr.add(p.getRegId());

        }

        DBController.statusArray = statusarr;
        contoller.getStatus(id, useridarr, 0);

        adapter = new CustomDeviceId(GetFriendDeviceId.this, namearr, useridarr, statusarr);
        list.setAdapter(adapter);

    }
}

答案 1 :(得分:1)

不断/定期轮询改变通常不是一个好主意。

在更新数据库以获得更好的性能时,您应该执行推送通知之类的操作。当一段代码更改了DB的内容时,它应该调用所有侦听器订阅者/或者广播消息。

您的活动/片段应该实现该侦听器,并刷新列表视图。这样,只有在DB中发生某些更改而不是在DB中查找更改并自行刷新时,才会刷新列表视图。

A listview can be refreshed by modifying the backing datasource of listview.
namearr = newnamearr;
...

newnamearr是listview的新内容。

然后拨打notifyDataSetChanged()

这段代码正在运行,但它们可能是更好的方法。 import java.util.ArrayList;

public class ListenerTest {
    public static void main(String[] args) {
        // simulation for activities.
        A a  = new A();
        a.simulateOnCreate();
        B b = new B();
        b.simulateOnCreate();

        DBChanger obj = new DBChanger();
        obj.changeDBContent();
    }
}

// this is class where all DB changes will occur.

class DBChanger{
    public void changeDBContent(){
        // some piece of Code that change the DB code.
        ArrayList<Listenable> subcribers = ListnerManager.getInstance().getSubscribersList();
        for(Listenable l: subcribers){
            l.onUpadateAvailable();
        }
    }
}

// This class should corresponds to Activity/Fragment in Android which will implement the listener

class A implements Listenable {


public void simulateOnCreate(){
    ListnerManager  maneger = ListnerManager.getInstance();
    maneger.setOnListenable(this);
}

@Override
public void onUpadateAvailable() {
    System.out.println("A---> onUpadateAvailable");

}

}

// This class is manager of listener.

class ListnerManager {
    public static ListnerManager instance = new ListnerManager();

    public static ListnerManager getInstance(){
        if(instance == null){
            instance = new ListnerManager();
        }
        return instance;
    }

    ArrayList<Listenable> subscriberlist = new ArrayList<Listenable>();

    public void setOnListenable(Listenable subcsriber) {
        subscriberlist.add(subcsriber);
    }

    public ArrayList<Listenable> getSubscribersList() {
        return subscriberlist;
    }
}

// Same as class A
class B implements Listenable {

    public void simulateOnCreate(){
        ListnerManager  maneger = ListnerManager.getInstance();
        maneger.setOnListenable(this);  
    }

    @Override
    public void onUpadateAvailable() {
        // TODO Auto-generated method stub
        System.out.println("B---> onUpadateAvailable");
    }   
}


interface Listenable {
    public void onUpadateAvailable();
}

我在控制台上收到的输出:

A---> onUpadateAvailable
B---> onUpadateAvailable

答案 2 :(得分:0)

我同意@GauravGupta。最好的方法是在数据库发生更改时实现推送通知。

但是关于你的问题,你可以尝试运行这个asynctask:

class refreshList extends AsyncTask<String, String, String> {
     Context context

    public refreshList(Context context){
       this.context=context;



        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method sstub
            Timer timer = new Timer();
                  timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // TODO Auto-generated method stub

//Since you cant invoke notify notifyDataSetChanged() inside the doInBackground. So we will use this code:
            ((MainActivity) context).runOnUiThread(new Runnable() {
                            public void run() {

                       //Do your code here like refreshing your adapter
                            MainActivity.adapter.notifyDataSetChanged();
                       //
                             }
                           });



            }
        }, 1000, 10000);
       //1000= interval delay;
       //10000= run every 10secs

            return null;
        }



    }

请记住在运行asynctask时传递活动的上下文。 new refreshList(this).execute();