安卓:刷新ListView的每一分钟 [英] Android: Refresh ListView every minute

查看:96
本文介绍了安卓:刷新ListView的每一分钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在读了一整天关于线程这个问题我想出了一个策略,但不能使它工作。

我有一个列表视图从SQL Server获取JSON数据
这个列表视图已经有一个上刷卡刷新功能

我需要这个列表视图自动刷新,只有当新的行插入数据基础。

所以我写了一个PHP文件获取的行数和它呼应难熬3秒刷新(在PHP本身),所以我每次进入PHP文件时,我得到我的表的实时行号。

我试图建立我MainActivity里面的函数:

  INT OldNumberOfRows =从PHP文件中的数据
而(真){
INT newNumberOfRows =再次使用PHP获取数据
如果(两者的arent相等)执行刷新命令。
}

请注意:我不知道如何提取我的AsyncTask的字符串开始操纵我的code与它

这是它在一般情况下,加Iv'e的主要活动中,外部类(FetchNumRowAsync)在PHP的刷卡类并调用PHP本身

MainActivity:

 公共类MainActivity扩展AppCompatActivity实现SwipeRefreshLayout.OnRefreshListener {    私有String TAG = MainActivity.class.getSimpleName();    私人字符串URL =htt​​p://troyka.esy.es/troyka/orders.php;
    私人SwipeRefreshLayout swipeRefreshLayout;
    私人的ListView ListView的;
    私人SwipeListAdapter适配器;
    私人列表<排序> orderList;    //开始偏移量将为0,以后在解析JSON更新
    私人INT偏移= 0;    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        新FetchRowNumAsync(本).execute(http://troyka.esy.es/numberofrows.php);        ListView控件=(ListView控件)findViewById(R.id.listView);
        //RelativeLayout.LayoutParams LAYOUT_DESCRIPTION =新RelativeLayout.LayoutParams(50,10);        //Rl.setLayoutParams(layout_description);        swipeRefreshLayout =(SwipeRefreshLayout)findViewById(R.id.swipe_refresh_layout);        orderList =新的ArrayList<>();
        适配器=新SwipeListAdapter(这一点,orderList);
        listView.setAdapter(适配器);        swipeRefreshLayout.setOnRefreshListener(本);        / **
         *上的活动显示刷卡刷新动画制作
         *由于动画将不启动的onCreate,可运行后使用
         * /
        swipeRefreshLayout.post(新的Runnable(){
                                    @覆盖
                                    公共无效的run(){
                                        swipeRefreshLayout.setRefreshing(真);                                        fetchOrders();
                                    }
                                }
        );    }    / **
     *当刷卡刷新拉低这种方法被称为
     * /
    @覆盖
    公共无效onRefresh(){
        fetchOrders();
    }    / **
     *通过HTTP调用抓取电影JSON
     * /
    私人无效fetchOrders(){        //显示发出HTTP调用之前刷新动画
        swipeRefreshLayout.setRefreshing(真);        //附加偏移网址
        字符串的URL = URL +偏移量;        //排球的JSON数组请求对象
        JsonArrayRequest REQ =新JsonArrayRequest(URL,
                新Response.Listener< JSONArray>(){
                    @覆盖
                    公共无效onResponse(JSONArray响应){
                        Log.d(TAG,response.toString());                        如果(response.length()大于0){                            //通过JSON循环,并增加订单列表
                            的for(int i = 0; I< response.length();我++){
                                尝试{
                                    JSONObject的orderObj = response.getJSONObject(I)                                    INT等级= orderObj.getInt(等级);
                                    字符串title = orderObj.getString(标题);                                    令M =新订单(等级,职称);                                    orderList.add(0,M);                                    //更新偏移值来最高值
                                    如果(排名> = OFFSET)
                                        偏移量=排名;                                }赶上(JSONException E){
                                    Log.e(TAG,JSON解析错误:+ e.getMessage());
                                }
                            }                            adapter.notifyDataSetChanged();
                        }                        //停止刷卡刷新
                        swipeRefreshLayout.setRefreshing(假);                    }
                },新Response.ErrorListener(){
            @覆盖
            公共无效onErrorResponse(VolleyError错误){
                Log.e(TAG,服务器错误:+ error.getMessage());                Toast.makeText(getApplicationContext(),error.getMessage(),Toast.LENGTH_LONG).show();                //停止刷卡刷新
                swipeRefreshLayout.setRefreshing(假);
            }
        });        //添加请求,请求队列
        MyApplication.getInstance()addToRequestQueue(REQ)。
    }}

FetchRowNumAsync:

 公共类FetchRowNumAsync扩展的AsyncTask<弦乐,太虚,字符串> {    私人语境mContext;    公共FetchRowNumAsync(上下文CTX){
        this.mContext = CTX;
    }    保护字符串doInBackground(字符串的URL ...)
    {
        串fullString =;
        尝试{
            网址URL =新的URL(网址[0]);
            读者的BufferedReader =新的BufferedReader(新的InputStreamReader(url.openStream()));
            串线;
            而((行= reader.readLine())!= NULL){
                fullString + =行;
            }
            reader.close();
        }赶上(例外五){
            e.getMessage();
        }
        返回fullString;
    }    @覆盖
    保护无效onPostExecute(字符串值){
        尝试{
            ((OnValueFetchedListener)mContext).onValueFetched(值);
        }赶上(抛出ClassCastException E){}
    }    公共接口OnValueFetchedListener {
        无效onValueFetched(字符串列);
    }}

SwipeListAdapter:

 公共类SwipeListAdapter延伸BaseAdapter {
        私人活动活动;
        私人LayoutInflater吹气;
        私人列表<排序> orderList;
        私有String [] bgColors;        公共SwipeListAdapter(活动活动,列表与LT;排序> orderList){
            this.activity =活动;
            this.orderList = orderList;
            bgColors = activity.getApplicationContext()getResources()getStringArray(R.array.movi​​e_serial_bg)。
        }        @覆盖
        公众诠释的getCount(){
            返回orderList.size();
        }        @覆盖
        公共对象的getItem(INT位置){
            返回orderList.get(位置);
        }        @覆盖
        众长getItemId(INT位置){
            返回的位置;
        }        @覆盖
        公共查看getView(INT位置,查看convertView,父母的ViewGroup){            如果(吹气== NULL)
                吹气=(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            如果(convertView == NULL)
                convertView = inflater.inflate(R.layout.list_row,NULL);            TextView的串行=(TextView中)convertView.findViewById(R.id.serial);
            TextView的标题=(TextView中)convertView.findViewById(R.id.title);            serial.setText(将String.valueOf(orderList.get(位置).ID));
            title.setText(orderList.get(位置).title伪);            串色= bgColors [位置%bgColors.length]。
            serial.setBackgroundColor(Color.parseColor(彩色));            返回convertView;
        }}

PHP

 < PHP
标题(刷新:3;);$库MySQLi =新的mysqli(无关,无关,无关,无关);/ *检查连接* /
如果(mysqli_connect_errno()){
    的printf(连接失败:%S \\ n,mysqli_connect_error());
    出口();
}$查询=SELECT COUNT(*)FROM指令;
$结果= mysqli_query($ mysqli的,$查询);
$行= mysqli_fetch_row($结果);回波($行[0]);$ result->关闭();$ mysqli->关闭();
?>


解决方案

当你已经在你的表添加/更新数据的服务器上,直到Android应用程序不会知道,除非你调用来自应用程序脚本,并获取数据和更新中您的设备。

只有当你的应用程序已经实现了这些功能的


  1. 推送通知的 - 调用脚本每次收到通知的时间

  2. XMPP服务的 - 用于聊天应用(没有可能回答
    你的问题现在)

下面是我的建议对你

从服务器端:


  • 在服务器上的表中创建时间戳字段。与更新
    当前时间戳值,每次你做改变(即更新/加载)的
    当在该脚本被称为table.and横跨在JSON发送
    使您的应用程序保存在源码与数据一起。


  • 服务器将比较时间戳发表与应用程序每次
    在服务器中的新数据保存的时间戳。


从客户端:


  • 从应用程序的拳头时戳将为0服务器将检查和
    发送整个数据与变化中保存的时间戳一起
    表。保存数据与时间戳一起。第二次当
    脚本叫做应用程序将派出上次的时间戳
    保存。

这一切您的应用程序不会来还知道如果添加新的数据,直到您调用脚本,并进行检查。但ATLEAST它会在接收或不新的数据知道是否刷新屏幕乌尔

现在来脚本中调用从正在assynch任务执行客户端的一部分,不要使用处理程序来执行assynch类每分钟它

 最后的处理程序timerHandler =新的处理程序();
    可运行timerRunnable;
timerRunnable =新的Runnable(){
            @覆盖
            公共无效的run(){
                新FetchRowNumAsync(上下文).execute(URL);
                timerHandler.postDelayed(timerRunnable,60000); //每分钟运行
            }
        };

和注销它的onDestroy()

  @覆盖
    公共无效onDestroyView(){
            // TODO自动生成方法存根
            super.onDestroyView();
            timerHandler.removeCallbacks(timerRunnable);        }

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\n", 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();
?>

解决方案

android app will not know when you have added/updated data in your table on the server until and unless you call script from app and fetch the data and update in your device.

only if your app has implemented these feature's

  1. push notification- call Script every time you receive notification.
  2. XMPP service- used for chat apps(which is not probably answer for your question right now)

here is my suggestion for you

From server side:

  • create timestamp field in your table on server. update it with current timestamp value every time you do changes(i.e update/add) in the table.and when when that script is called send it across in json and make your app save it in sqlite along with data.

  • server will compare for timestamp posted by app everytime with the saved timestamp in the server for new data.

from client side:

  • for fist time timestamp from app will be 0. server will check it and send the whole data along with the timestamp saved during changes in table. save the data along with time stamp . second time when the script is called App will be sending the timestamp that was last saved.

with all this your app will not come to know still if new data is added until you call script and check. but atleast it will come to know if new data is received or not and whether to refresh ur screen

now comes script calling part from client side that is executing of assynch task, do it using handler to execute assynch class every minute

final Handler timerHandler = new Handler();
    Runnable timerRunnable;


timerRunnable = new Runnable() {
            @Override
            public void run() {
                new FetchRowNumAsync(context).execute(url);
                timerHandler.postDelayed(timerRunnable, 60000); // run every minute
            }
        };

and unregister it in onDestroy()

@Override
    public void onDestroyView() {
            // TODO Auto-generated method stub
            super.onDestroyView();
            timerHandler.removeCallbacks(timerRunnable);

        }

这篇关于安卓:刷新ListView的每一分钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆