Android:每分钟刷新ListView

时间:2015-09-11 19:02:34

标签: android

我一直在阅读关于这个问题的全天候线索,我想出了一个策略,但却无法使其发挥作用

我有一个listview从sql server获取json数据 此列表视图已具有刷卡刷新功能

我只需要在数据库中插入新行时自动刷新此列表视图。

所以我写了一个获取行数的php文件并用3秒刷新回复它(在php本身上)所以每次我输入php文件时我都得到了我的表的实时行号。

我正在尝试在MainActivity中构建一个函数:

db.php

注意:我不知道如何从我的asynctask中提取字符串以开始用它来操作我的代码。

这就是一般情况,Iv'e添加了主要活动,“外部类”(FetchNumRowAsync)调用php刷卡类和php本身

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.
}

FetchRowNumAsync:

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);
    }

}

SwipeListAdapter:

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);
    }

}

PHP

   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;
        }

}

2 个答案:

答案 0 :(得分:0)

尝试这种方法:

  • 在服务器中创建一个端点,如下所示:

    //http://somesite.com/api/data/pull/check
    
  • 然后,您可以轻松检查此端点是否返回某些值,如 true false ,具体取决于是否有新数据插入数据库。

  • 根据您收到的结果,您可以决定是否通过发出其他HTTP请求来刷新手机上的数据。您总是希望避免向服务器发出不必要的请求 - 请记住用户每次使用他们的数据计划(服务)时都会花钱。

  • 我和上面的评论一样,建议您设置一个时间戳列,您可以检查以便只获取新添加的数据而不是所有内容!

我希望这能让您简单了解如何解决这个问题!祝你好运!

答案 1 :(得分:0)

Android应用程序将不知道您在服务器上的表中添加/更新数据的时间,除非您从应用程序调用脚本并获取数据并在设备中更新。

仅当您的应用已实施这些功能

  1. 推送通知 - 每次收到通知时都会调用脚本。
  2. XMPP服务 - 用于聊天应用程序(这可能不是答案 你现在的问题)
  3. 这是我对你的建议

    从服务器端:

    • 在服务器上的表中创建时间戳字段。用它来更新它 每次进行更改(即更新/添加)时的当前时间戳值 table.and何时调用该脚本在json中发送它 并使你的应用程序将其与数据一起保存在sqlite中。

    • 服务器将比较app每次发布的时间戳 在服务器中为新数据保存了时间戳。

    客户端

    • 从app开始的第一个时间戳将是0.服务器将检查它和 发送整个数据以及更改期间保存的时间戳 表。保存数据和时间戳。第二次的时候 脚本被调用App将发送最后一个时间戳 保存。

    在您调用脚本并检查之前,如果添加了新数据,您的应用程序将无法知道。但至少会知道是否收到新数据以及是否刷新你的屏幕

    现在来自客户端的脚本调用部分正在执行assynch任务,使用handler来执行每分钟执行assynch类

    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
                }
            };
    

    并在onDestroy()

    中取消注册
    @Override
        public void onDestroyView() {
                // TODO Auto-generated method stub
                super.onDestroyView();
                timerHandler.removeCallbacks(timerRunnable);
    
            }