联网请求数据+更新ListView的UI——学习笔记

联网的框架有很多,我试着分别用了两个,一个是Volley,一个是Okhttp。在使用过程中,有大大小小的坑,把我这两天的时间都浪费光了,不过解决这些问题后我确实又明白了很多知识,虽然这些知识在之前看书的时候都学过,但是理解不够,用的时候自然无从下手,现在明白一些了,就把这些都记录一下。

首先说一下使用过程中的坑吧,第一个坑,我在用volley去请求网络后,然后在volley请求成功的回调方法里面打印了请求数据,结果一直请求失败,因为我请求了十三个地址,然后把所有请求队列放在一个循环里,这样去请求,结果自然不行,后来我查询资料,发现原来Volley是要把多个请求放在一个队列,而不是创建多个只包含一个请求的队列。然后我就把请求放在一个队列中

public void getDateByVolley(){
        RequestQueue queue = Volley.newRequestQueue(context);
        for (int i = 0 ; i < Constants.all_urls.length; i++){
            queue.add(getDataFromNetByVolley(Constants.all_urls[i]));
        }
    }

结果发现还是没有网络,坑爹了。。。。又通过查资料,发现volley可以设置请求网络失败时重新请求,只要

request.setRetryPolicy(new DefaultRetryPolicy(10 * 1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//默认最大尝试次数
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT )); //设置请求失败的时候重试

然后请求网络得到数据了:
这里写图片描述

结果坑爹的又来了,我在volley请求网络成功回调的onResponse方法里面获取的数据居然不能在这个方法之外使用,而且因为请求是耗时的,你无法在onResponse方法外面去正确的判断数据的状态。

比如上图中,volley每请求成功一次,我就把获取的数据添加到一个集合中,然后打印这个集合list的长度,它是递增的,结果我在onResponse方法之外去打印list的长度(list是全局变量),不管在哪里打印,不管我怎么使用if,when,结果都为0,list也为null。

后来我思考了很久很久,终于想明白了,由于网络请求是一个耗时操作,这里请求十几个地址全部完成大概要十几秒,所以我在onResponse方法外去判断是没有效果的,因为时间不同步,我连请求都没完成,判断就结束了,必须要在网络请求完成后发送一个通知才行。

这时候我想到了AsyncTask,结果不行,在网上查资料发现,volley已经封装了异步请求网络,也就是说它的网络请求是

然后我又思考了很久很久,终于想到了两个方法,第一个是使用Handler,第二个是通过构造函数的方法。

Handler就不谈了,我最开心的是想到了构造函数的方法,比如说我想用这些数据设置ListView的适配器,只需要创建一个ListView的适配器,然后在适配器里添加一个构造函数,这个构造函数的构造参数有我想要的数据就行,这样就可以把数据传递给适配器了。

然后使用okhttp需要注意的一点是,在okhttp请求成功的回调方法中,不是在主线程里,而volley请求成功的回调方法是在主线程里的,所以前者需要开启主线程才能更新UI,后者则可以直接在volley中更新UI。接下来就是大致的代码了:

public class MainActivity extends AppCompatActivity {

    private ListView listView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listview);
        try {
            initData();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void initData() throws JSONException {
        LogUtil.e("页面数据被初始化——");
        String saveJson = CacheUtils.getString(MainActivity.this, Constants.all_urls[0]);
        if (!TextUtils.isEmpty(saveJson)){
            processData(saveJson);
        }
//        getDateByVolley();
        getDataByOkhttp(Constants.all_urls[0]);

    }

    public void getDateByVolley(){
        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(getDataFromNetByVolley(Constants.all_urls[0]));
    }


    private StringRequest getDataFromNetByVolley(final String url){

        final StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                LogUtil.e("使用Volley联网请求数据成功——" + response);

                //缓存数据
                CacheUtils.putString(MainActivity.this, url, response);

                    NewsTopBeanAuto bean = HttpUtil.parsedJsonWithGson(response);
                    String title = bean.getResult().getResult().getChannel();
                    processData(response);
                    LogUtil.e("数据解析成功,标题是——" + title );
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                LogUtil.e("使用Volley联网请求数据失败——" + error.getMessage());
            }
        }){
            @Override
            protected Response<String> parseNetworkResponse(NetworkResponse response) {
                try {
                    String parsed = new String(response.data, "UTF-8");
                    return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                return super.parseNetworkResponse(response);
            }
        };
        request.setRetryPolicy(new DefaultRetryPolicy(10 * 1000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//默认最大尝试次数
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT )); //设置请求失败的时候重试
        return request;
    }


    private void processData(String json) {
        final NewsTopBeanAuto bean = HttpUtil.parsedJsonWithGson(json);

        String title = bean.getResult().getResult().getChannel();
        List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen = bean.getResult().getResult().getList();
        LogUtil.e("解析Json数据成功----title----:" + title);
        if (listBeen != null){
            listView.setAdapter(new MyListViewAdapter(listBeen));
        }
    }

    private void getDataByOkhttp(String url){
        HttpUtil.sendOkHttpRequest(url, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.e("使用okhttp失败~~~");
            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) throws IOException {
                LogUtil.e("使用okhttp成功~~~当前线程是——" + Thread.currentThread().getName());
                final String data = response.body().string();
                NewsTopBeanAuto bean = HttpUtil.parsedJsonWithGson(data);
                String title = bean.getResult().getResult().getChannel();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        processData(data);
                    }
                });
                LogUtil.e("数据解析成功,标题是——" + title );

            }
        });
    }


    private class MyListViewAdapter extends BaseAdapter {
        List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen;


        public MyListViewAdapter(List<NewsTopBeanAuto.ResultBeanX.ResultBean.ListBean> listBeen) {
            this.listBeen = listBeen;
        }

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

        @Override
        public Object getItem(int position) {
            return null;
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
            if (convertView == null){
                convertView = View.inflate(MainActivity.this, R.layout.listview_detail, null);
                viewHolder = new ViewHolder();
                viewHolder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
                viewHolder.tv_time = (TextView) convertView.findViewById(R.id.tv_time);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            String data1 = listBeen.get(position).getTitle();
            String data2 = listBeen.get(position).getTime();
            viewHolder.tv_title.setText(data1);
            viewHolder.tv_time.setText(data2);
            LogUtil.e("内容是——" + data1 + data2);
            return convertView;
        }
    }

    private class ViewHolder {
        TextView tv_title;
        TextView tv_time;
    }
}

粗略效果大概是这样:
这里写图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值