开源框架学习之--网络篇(基础一)

本系列主要记录学习android开发网络请求和图片加载框架的使用。

网络操作时官方一般都会介绍HttpClient以及HttpConnection这两个包。前者是apache的开源库,后者是android自带的api。二者进行一个比较,谷歌在官方文档已经说明了,建议在2.3以及以上版本使用 HttpConnection。具体原因呢,是因为对2.1和2.2版本,HttpURLConnection有那么几个Bug,所以建议用Apache 的HTTP Client;之后的版本,建议用HttpURLConnection。android 开发团队不应该维护该库而是转投更为轻量级的httpurlconnection。

当我们开发企业级应用的时候,一般都会选择使用已经封装好的http框架。开源的比较流行的有:

1、volley 官方推出的网络请求框架

下载地址:https://android.googlesource.com/platform/frameworks/volley

2、loopj/android-async-http

下载地址:https://github.com/loopj/android-async-http

官方文档:http://loopj.com/android-async-http/

demo地址:https://github.com/loopj/android-async-http/tree/1.4.9/sample/src/main/java/com/loopj/android/http/sample

3、koush/AndroidAsync 基于nio的异步通信库

下载地址:https://github.com/koush/AndroidAsync

4. Asynchronous Http Client for Android Android异步Http请求

项目地址:https://github.com/loopj/android-async-http

文档介绍:http://loopj.com/android-async-http/

5. android-query 异步加载,更少代码完成Android加载

项目地址:https://github.com/androidquery/androidqueryhttps://code.google.com/p/android-query/

文档介绍:https://code.google.com/p/android-query/#Why_AQuery?

Demo地址:https://play.google.com/store/apps/details?id=com.androidquery

特点:https://code.google.com/p/android-query/#Why_AQuery?

6. Async Http Client Java异步Http请求

项目地址:https://github.com/AsyncHttpClient/async-http-client

文档介绍:http://sonatype.github.io/async-http-client/

7. Ion 支持图片、json、http post等异步请求

项目地址:https://github.com/koush/ion

文档介绍:https://github.com/koush/ion#more-examples

8. HttpCache Http缓存

项目地址:https://github.com/Trinea/AndroidCommon

Demo地址:https://github.com/Trinea/TrineaDownload/blob/master/TrineaAndroidDemo.apk?raw=true

Demo代码:https://github.com/Trinea/AndroidDemo/blob/master/src/cn/trinea/android/demo/HttpCacheDemo.java

9. Http Request

项目地址:https://github.com/kevinsawicki/http-request

文档介绍:https://github.com/kevinsawicki/http-request#examples

10. okhttp square开源的http工具类

项目地址:https://github.com/square/okhttp

文档介绍:http://square.github.io/okhttp/

11. Retrofit RESTFUL API设计

项目地址:https://github.com/square/retrofit

文档介绍:http://square.github.io/retrofit/

图片加载框架:

1. Android-Universal-Image-Loader 图片缓存

目前使用最广泛的图片缓存,支持主流图片缓存的绝大多数特性。

项目地址:https://github.com/nostra13/Android-Universal-Image-Loader

Demo地址:https://github.com/Trinea/TrineaDownload/blob/master/universal-imageloader-demo.apk?raw=true

文档介绍:http://www.intexsoft.com/blog/item/74-universal-image-loader-part-3.html

2. picasso square开源的图片缓存

项目地址:https://github.com/square/picasso

文档介绍:http://square.github.io/picasso/

3. ImageCache 图片缓存,包含内存和Sdcard缓存

项目地址:https://github.com/Trinea/AndroidCommon

Demo地址:https://github.com/Trinea/TrineaDownload/blob/master/TrineaAndroidDemo.apk?raw=true

文档介绍:http://www.trinea.cn/?p=704

4、facebook/fresco 快速而高效图片加载

项目地址:https://github.com/facebook/fresco

文档介绍:https://code.facebook.com/posts/366199913563917(译文:               http://android.jobbole.com/80922/)

5、bumptech/glide 图片加载和缓存库

Glide的详细介绍:http://www.oschina.net/p/glide

Glide的下载地址:https://github.com/bumptech/glide

1. Volley简介

除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。

下图所示的这些应用都是属于数据量不大,但网络通信频繁的,因此非常适合使用Volley。

StringRequest的用法

前面已经说过,Volley的用法非常简单,那么我们就从最基本的HTTP通信开始学习吧,即发起一条HTTP请求,然后接收HTTP响应。首先需要获取到一个RequestQueue对象,可以调用如下方法获取到:

RequestQueue mQueue = Volley.newRequestQueue(context);

注意这里拿到的RequestQueue是一个请求队列对象,它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非常合适高并发的,因此我们不必为每一次HTTP请求都创建一个RequestQueue对象,这是非常浪费资源的,基本上在每一个需要和网络交互的Activity中创建一个RequestQueue对象就足够了。

接下来为了要发出一条HTTP请求,我们还需要创建一个StringRequest对象,如下所示:

StringRequest stringRequest =new StringRequest(“http://www.baidu.com”,

new Response.Listener() {

@Override

public voidon Response(String response) {

Log.d(“TAG”, response);

}

},new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

Log.e(“TAG”, error.getMessage(), error);

}

});

可以看到,这里new出了一个StringRequest对象,StringRequest的构造函数需要传入三个参数,第一个参数就是目标服务器的URL地址,第二个参数是服务器响应成功的回调,第三个参数是服务器响应失败的回调。其中,目标服务器地址我们填写的是百度的首页,然后在响应成功的回调里打印出服务器返回的内容,在响应失败的回调里打印出失败的详细信息。

最后,将这个StringRequest对象添加到RequestQueue里面就可以了,如下所示:

mQueue.add(stringRequest);

另外,由于Volley是要访问网络的,因此不要忘记在你的AndroidManifest.xml中添加如下权限:

好了,就是这么简单,如果你现在运行一下程序,并发出这样一条HTTP请求,就会看到LogCat中会打印出如下图所示的数据。

这样的话,一个最基本的HTTP发送与响应的功能就完成了。你会发现根本还没写几行代码就轻易实现了这个功能,主要就是进行了以下三步操作:

1. 创建一个RequestQueue对象。

2. 创建一个StringRequest对象。

3. 将StringRequest对象添加到RequestQueue里面。

不过大家都知道,HTTP的请求类型通常有两种,GET和POST,刚才我们使用的明显是一个GET请求,那么如果想要发出一条POST请求应该怎么做呢?StringRequest中还提供了另外一种四个参数的构造函数,其中第一个参数就是指定请求类型的,我们可以使用如下方式进行指定:

StringRequest stringRequest =newStringRequest(Method.POST, url,  listener, errorListener);

可是这只是指定了HTTP请求方式是POST,那么我们要提交给服务器的参数又该怎么设置呢?很遗憾,StringRequest中并没有提供设置POST参数的方法,但是当发出POST请求的时候,Volley会尝试调用StringRequest的父类——Request中的getParams()方法来获取POST参数,那么解决方法自然也就有了,我们只需要在StringRequest的匿名类中重写getParams()方法,在这里设置POST参数就可以了,代码如下所示:

StringRequest stringRequest =new  StringRequest(Method.POST, url,  listener, errorListener) {

@Override

protected Map getParams() throws AuthFailureError {

Map map =newHashMap();

map.put(“params1″,”value1”);

map.put(“params2″,”value2”);

returnmap;

}

};

 JsonRequest的用法

学完了最基本的StringRequest的用法,我们再来进阶学习一下JsonRequest的用法。类似于StringRequest,JsonRequest也是继承自Request类的,不过由于JsonRequest是一个抽象类,因此我们无法直接创建它的实例,那么只能从它的子类入手了。JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayRequest,从名字上你应该能就看出它们的区别了吧?一个是用于请求一段JSON数据的,一个是用于请求一段JSON数组的。

至于它们的用法也基本上没有什么特殊之处,先new出一个JsonObjectRequest对象,如下所示:

JsonObjectRequest jsonObjectRequest =new JsonObjectRequest(url,null,

newResponse.Listener() {

@Override

public voidon Response(JSONObject response) {

Log.d(“TAG”, response.toString());

}

},newResponse.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

Log.e(“TAG”, error.getMessage(), error);

}

});

最后再将这个JsonObjectRequest对象添加到RequestQueue里就可以了,如下所示:

mQueue.add(jsonObjectRequest);

由此可以看出,服务器返回给我们的数据确实是JSON格式的,并且onResponse()方法中携带的参数也正是一个JSONObject对象,之后只需要从JSONObject对象取出我们想要得到的那部分数据就可以了。

2、OkHttp是一个高效的Http客户端,有如下的特点:

支持HTTP2/SPDY黑科技

socket自动选择最好路线,并支持自动重连

拥有自动维护的socket连接池,减少握手次数

拥有队列线程池,轻松写并发

拥有Interceptors轻松处理请求与响应(比如透明GZIP压缩,LOGGING)

基于Headers的缓存策略

源码分析地址:http://www.jianshu.com/p/aad5aacd79bf

使用教程:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

基本使用

privateRequest request;

private static OkHttpClient client =new OkHttpClient();

/**

* 在这里直接设置连接超时,静态方法内,在构造方法被调用前就已经初始话了

*/

static{

client.newBuilder().connectTimeout(10, TimeUnit.SECONDS);

client.newBuilder().readTimeout(10, TimeUnit.SECONDS);

client.newBuilder().writeTimeout(10, TimeUnit.SECONDS);

}

//get请求同步方法

new Thread( new  Runnable ( ) {

    @Override

      public void run( ) {

            try{

                request =new Request.Builder( ).url(Contants.SYNC_URL).build( );

                 Response response = client.newCall(request).execute( );

                 result = response.body( ).string( );

                 runOnUiThread(new Runnable( ) {

                                    @Override  public  void  run( ) {

                                                 tvtext.setText(result);

                                                Log.d(“MainActivity”,”hello”);

                                     }

                       });

                }catch(Exception e) {

                  e.printStackTrace();

            }

    }

 }).start();

//异步GET:

new   Thread(  new Runnable( ) {

@Override public void run( ) {

        request =new Request.Builder().url(Contants.ASYNC_URL).build( );

        client.newCall(request).enqueue(new Callback() {

/**                   

 * A call is a request that has been prepared for execution. A call can be canceled. As       this object                   

 * represents a single request/response pair (stream), it cannot be executed twice.                   

  *@paramcall  是一个接口,  是一个准备好的可以执行的request                

  *              可以取消,对位一个请求对象,只能单个请求   @parame                    

 */

@Override public void onFailure(Call call, IOException e) {

                        Log.d(“MainActivity”,”请求失败”);

}

/**                  

 *@paramcall                   

 *@paramresponse  是一个响应请求                    

*@throwsIOException                    

 */

@Override 

public void onResponse(Call call, Response response)throws IOException {

/**

* 通过拿到response这个响应请求,然后通过body().string(),拿到请求到的数据

* 这里最好用string()  而不要用toString()

* toString()每个类都有的,是把对象转换为字符串

* string()是把流转为字符串

*/

             result = response.body().string();

             runOnUiThread(new Runnable() {

                     @Override

                    public void run( ) {

                             tvtext.setText(result);

                                          }

                                });

                   }

          });

       }

}).start();

//文件下载地址

String url =”your_URL”;

request =new Request.Builder().url(url).build();

OkHttpClient client =newOkHttpClient();

client.newCall(request).enqueue(new Callback() {

               @Override

              public void onFailure(Call call, IOException e) {

              }

@Override

public void onResponse(Call call, Response response)throws IOException {

//把请求成功的response转为字节流

InputStream inputStream = response.body().byteStream();

/**

* 在这里要加上权限  在mainfests文件中

*/

//在这里用到了文件输出流

FileOutputStream fileOutputStream =newFileOutputStream(newFile(“/sdcard/logo.jpg”));

byte[] buffer =newbyte[2048];//定义一个字节数组

int len =0;

while((len = inputStream.read(buffer)) != -1) {//写出到文件

fileOutputStream.write(buffer,0, len);

}

fileOutputStream.flush();//关闭输出流

Log.d(“wuyinlei”,”文件下载成功…”);

}

});

未完待续!!!!

    原文作者:Zaker2Magic
    原文地址: https://www.jianshu.com/p/3e22a7ab690e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞