Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
169 views
in Technique[技术] by (71.8m points)

Android: Refresh ListView every minute

I've been reading all day threads regarding this issue I came up with a strategy but can't make it work

I have a listview fetching json data from a sql server this listview already has a on swipe refresh function

I need this listview to refresh automatically only when new row was inserted in the data base.

So I wrote a php file fetching number of rows and echoing it witha 3 second refresh (on the php itself) so every time I enter the php file I get the realtime row numbers of my table.

I'm trying to build a function inside my MainActivity:

int OldNumberOfRows = data from the php file
while(true){
int newNumberOfRows = fetch data again using that php
if(both arent equal) execute refresh command.
}

Note: I got no idea how to extract the string from my asynctask to start manipulating my code with it.

That's it in general, Iv'e added the main activity , the "outer class" (FetchNumRowAsync) calling that php the swipe class and the php itself

MainActivity:

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    private String TAG = MainActivity.class.getSimpleName();

    private String URL = "http://troyka.esy.es/troyka/orders.php";


    private SwipeRefreshLayout swipeRefreshLayout;
    private ListView listView;
    private SwipeListAdapter adapter;
    private List<Order> orderList;

    // initially offset will be 0, later will be updated while parsing the json
    private int offSet = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new FetchRowNumAsync(this).execute("http://troyka.esy.es/numberofrows.php");

        listView = (ListView) findViewById(R.id.listView);
        //RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(50,10);

        //Rl.setLayoutParams(layout_description);

        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);

        orderList = new ArrayList<>();
        adapter = new SwipeListAdapter(this, orderList);
        listView.setAdapter(adapter);

        swipeRefreshLayout.setOnRefreshListener(this);

        /**
         * Showing Swipe Refresh animation on activity create
         * As animation won't start on onCreate, post runnable is used
         */
        swipeRefreshLayout.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        swipeRefreshLayout.setRefreshing(true);

                                        fetchOrders();
                                    }
                                }
        );

    }

    /**
     * This method is called when swipe refresh is pulled down
     */


    @Override
    public void onRefresh() {
        fetchOrders();
    }

    /**
     * Fetching movies json by making http call
     */
    private void fetchOrders() {

        // showing refresh animation before making http call
        swipeRefreshLayout.setRefreshing(true);

        // appending offset to url
        String url = URL + offSet;

        // Volley's json array request object
        JsonArrayRequest req = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.d(TAG, response.toString());

                        if (response.length() > 0) {

                            // looping through json and adding to order list
                            for (int i = 0; i < response.length(); i++) {
                                try {
                                    JSONObject orderObj = response.getJSONObject(i);

                                    int rank = orderObj.getInt("rank");
                                    String title = orderObj.getString("title");

                                    Order m = new Order(rank, title);

                                    orderList.add(0, m);

                                    // updating offset value to highest value
                                    if (rank >= offSet)
                                        offSet = rank;

                                } catch (JSONException e) {
                                    Log.e(TAG, "JSON Parsing error: " + e.getMessage());
                                }
                            }

                            adapter.notifyDataSetChanged();
                        }

                        // stopping swipe refresh
                        swipeRefreshLayout.setRefreshing(false);

                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Server Error: " + error.getMessage());

                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();

                // stopping swipe refresh
                swipeRefreshLayout.setRefreshing(false);
            }
        });

        // Adding request to request queue
        MyApplication.getInstance().addToRequestQueue(req);
    }

}

FetchRowNumAsync:

public class FetchRowNumAsync extends AsyncTask<String, Void, String>  {

    private Context mContext;

    public FetchRowNumAsync(Context ctx){
        this.mContext = ctx;
    }

    protected String doInBackground(String... urls)
    {
        String fullString = "";
        try{
            URL url = new URL(urls[0]);
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                fullString += line;
            }
            reader.close();
        }catch(Exception e ){
            e.getMessage();
        }
        return fullString;
    }

    @Override
    protected void onPostExecute(String value){
        try{
            ((OnValueFetchedListener) mContext).onValueFetched(value);
        }catch(ClassCastException e){}
    }

    public interface OnValueFetchedListener{
        void onValueFetched(String columns);
    }

}

SwipeListAdapter:

   public class SwipeListAdapter extends BaseAdapter {
        private Activity activity;
        private LayoutInflater inflater;
        private List<Order> orderList;
        private String[] bgColors;

        public SwipeListAdapter(Activity activity, List<Order> orderList) {
            this.activity = activity;
            this.orderList = orderList;
            bgColors = activity.getApplicationContext().getResources().getStringArray(R.array.movie_serial_bg);
        }

        @Override
        public int getCount() {
            return orderList.size();
        }

        @Override
        public Object getItem(int location) {
            return orderList.get(location);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            if (inflater == null)
                inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (convertView == null)
                convertView = inflater.inflate(R.layout.list_row, null);

            TextView serial = (TextView) convertView.findViewById(R.id.serial);
            TextView title = (TextView) convertView.findViewById(R.id.title);

            serial.setText(String.valueOf(orderList.get(position).id));
            title.setText(orderList.get(position).title);

            String color = bgColors[position % bgColors.length];
            serial.setBackgroundColor(Color.parseColor(color));

            return convertView;
        }

}

PHP

<?php
header("refresh: 3;");

$mysqli = new mysqli("irrelevant","irrelevant","irrelevant","irrelevant");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s
", mysqli_connect_error());
    exit();
}

$query = "SELECT COUNT(*) FROM orders";
$result = mysqli_query($mysqli,$query);
$rows = mysqli_fetch_row($result);

echo ($rows[0]);   

$result->close();

$mysqli->close();
?>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this approach:

  • Create an endpoint in your server like the following:

    //http://somesite.com/api/data/pull/check
    
  • Then, you can easily check this endpoint that returns some value like true or false depending on whether there is new data inserted into the db.

  • From the result you receive, you can then decide on whether to refresh your data on the phone by making another HTTP request or not. You always want to avoid making unnecessary requests to the server - remember users spend money every time they use their data plan (service).

  • I, like in the comments above, recommend having a column with a timestamp that you can check so that you only get the newly added data instead of everything!

I hope this gives you a simple idea on how to approach this issue! Good luck!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...