联网的框架有很多,我试着分别用了两个,一个是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请求成功