本帖最后由 世事繁华皆成空 于 2016-1-18 17:38 编辑
在安卓4.0以后,Android已不允许在主线程中请求网络,对于这类可能会耗时的操作,放在主线程中运行的话会给用户带来非常不好的用户体验,并且在安卓5.0以后,Google彻底抛弃了Apache的HttpClient网络请求方式,并推出了一个轻量级的Volley网络框架
一个常见的网络请求方式,以Gankio妹纸为例:
[Java] 纯文本查看 复制代码 public static void httpUrlConnectionGet() {
new Thread(new Runnable() { //新起一个线程,把网络请求放在这里
@Override
public void run() {
InputStream in = null;
BufferedReader br = null;
HttpURLConnection conn = null;
URL url = null;
try {
String en = URLEncoder.encode("福利", "UTF-8"); //对请求的网址进行url编码,很多网站对中文的识别很不好,不进行编码的话很有可能无法获取数据
url = new URL("http://gank.avosapps.com/api/data/" + en + "/10/1");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000); //设置请求方式和超时时长
in = conn.getInputStream(); //获取请求到的数据流
br = new BufferedReader(new InputStreamReader(in, "UTF-8")); //把流转为bufferReader
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line); //循环读取
}
System.out.println(sb.toString());
br.close();
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
}).start(); //启动线程
}
上面就是一个最简单的网络请求方式,接下来会在控制窗口输出返回的数据
数据已经完美的获取到了,这是一段json数据,接下来的事就是解析json标签了,这个本文不做演示
这里可以看到上述的代码只是单纯的完成一个访问网络的操作,却写了那么多代码,还要注意关闭连接等等操作,虽然也是目前的主流网络请求框架,但对于我们个人来说,未免还是有些复杂了
Volley是2013年Google在I/O大会上发布的一款轻量级网络请求框架,一个简单的例子
Volley主要是基于队列进行管理的,那么就需要一个全局管理的方法,一个最简单的方式
[Java] 纯文本查看 复制代码 public class App extends Application {
public static RequestQueue requestQueue;
@Override
public void onCreate() {
super.onCreate();
requestQueue = Volley.newRequestQueue(this);
}
}
声明一个全局静态变量requestQueue,并在App初始化的进行实例化,接下来我们就可以在代码中进行使用了
[Java] 纯文本查看 复制代码 public void VolleyTest() {
StringRequest stringRequest = new StringRequest("http://gank.avosapps.com/api/data/%E7%A6%8F%E5%88%A9/10/1", new Response.Listener<String>() {
//这里只需要简单的定义请求的网址,正确返回数据的监听器和失败的监听器
@Override
public void onResponse(String s) {
Log.e("TAG", s.toString()); //正确访问后就可以在这里获取到数据
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
}
});
stringRequest.setTag("qtfreet");
App.requestQueue.add(stringRequest); //设置请求的TAG,将该请求添加到队列中即可,设置TAG的好处就是方便之后的管理
}
Volley是基于异步请求的,所以你完全不用担心在请求过程中会堵塞主线程,但我们发现,上述访问返回的数据是个json格式的数据,不妨我们直接以json返回即可
[Java] 纯文本查看 复制代码 public void VolleyTest() {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "", new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
Log.e("TAG",jsonObject.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
}
});
jsonObjectRequest.setTag("qtfreet");
App.requestQueue.add(jsonObjectRequest);
}
这里返回的数据就直接格式化为json了,接下来就跟上面一样,解析json数据获取自己想要的内容即可
我们可以发现,Volley的请求方式要比HttpUrlConnection简单的多,而且高效,但是Volley也有自己不足的地方,对于大型数据,Volley就力不从心了,Volley无法将数据以流的形式返回,那就说明,Volley无法用来进行下载操作,一般的,我们用他来加载文字数据和图片数据
Okhttp:
Okhttp是著名开源组织square的开发的一款网络框架,优势在于
支持SPDY,允许连接同一主机的所有请求分享一个socket。 如果SPDY不可用,会使用连接池减少请求延迟。 使用GZIP压缩下载内容,且压缩操作对用户是透明的。 利用响应缓存来避免重复的网络请求。 当网络出现问题的时候,OKHttp会依然有效,它将从常见的连接问题当中恢复。 如果你的服务端有多个IP地址,当第一个地址连接失败时,OKHttp会尝试连接其他的地址,这对IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的。
因此使用 OkHttp 作为替代是好的选择.
而且常规方法下,Okhttp的使用难度几乎和Volley相同,非常简单
[Java] 纯文本查看 复制代码 public static void OkhttpTest() {
OkHttpClient ok = new OkHttpClient(); //实例化OkHttpClient
Request req = new Request.Builder().url("http://gank.avosapps.com/api/data/福利/10/1").build(); //创建请求队列
ok.newCall(req).enqueue(new Callback() { //创建一个新的Call来请求数据
@Override
public void onResponse(Response arg0) throws IOException {
System.out.println(arg0.body().string());
}
@Override
public void onFailure(Request arg0, IOException arg1) {
}
});
}
这里是直接可以返回数据了,当然还有一种写法
[Java] 纯文本查看 复制代码 public static String OkhttpTest() throws IOException {
OkHttpClient ok = new OkHttpClient();
Request req = new Request.Builder().url("http://gank.avosapps.com/api/data/福利/10/1").build();
Response res = ok.newCall(req).execute();
if (res.isSuccessful()) {
return res.body().string();
}
return null;
}
两种方式都是一样的,而且Okhttp支持数据流操作,这相较于Volley是有绝对的优势,如上的res获取他的流就是res.body().byteStream(),但这并不能就把Volley给一票否决了
两者都有各自的优势和缺点,两者兼用才是王道
项目地址:
volley:https://github.com/mcxiaoke/android-volley
Okhttp:https://github.com/square/okhttp
最后补上gankio几张妹纸图
|