天天看点

Android REST Clients 实践-官方实现

Android程序中REST Clients是一个很常见的使用场景,不过一些书籍介绍的都是很入门的网络访问,离在程序实际使用的场景还差的很远,今天我大概介绍一下自己的实践经验

网络访问

要作REST Client网络访问时第一步,一般认为2.3之前用Apache HttpClient,2.3之后使用HttpURLConnection具体原因参见这里,因为无论是HttpClient和HttpURLConnection书中都有介绍,此处就不展开了。

不过实际使用中HttpURLConnection还是很繁琐的,我一般在需要网络请求的地方会采用OkHttp,此处引用一下OkHttp官网的一段GET请求代码大家看看

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}
           

异步请求

虽然有了网络请求的代码,但是在Android中是不允许在ui线程进行网络请求的,官方的解决方法有两个

1. 新建一个Work Thread进行网络请求,请求结束之后使用Handler再切换到UI线程继续结果处理。具体实现参见这里

2. 使用AsyncTask

AsyncTask写起来很简单,一般大家都会采用AsyncTask。两个方案也都有无数实现示例,此处聊一些需要注意的点

1. AsyncTask其实可以看做Work Thread+Handler的封装

2. AsyncTask一个示例只能执行一次,所以如果有重复后台任务-》前台任务这种切换场景的话Work Thread+Handler是更好的选择。

3. AsyncTask本身存在一些缺陷,另外各版本AsyncTask实现也有些差异使用时需要注意AsyncTask中的线程池的策略是否满足你当前的情景

4. 一般使用Handler的时候会用匿名类实现,使用AsyncTask的时候会使用内部类。这两个常见的场景都容易造成内存泄漏,使用时需注意。

5. AsyncTask或者Work Thread + Handler的方案实际使用中需考虑Activity LifeCycle变化,这块内容后续会详细讨论

序列化

RESTFul接口一般会返回json结果,使用HttpURLConnection读到的是json 字符串。我们一般使用的是数据对象,此时我们要将读到的字符串序列化为合适的对象。最常见的解决方案就是Google的Gson,此处引用部分文档代码大家看一下

class BagOfPrimitives {
  private int value1 = ;
  private String value2 = "abc";
  private transient int value3 = ;
  BagOfPrimitives() {
    // no-args constructor
  }
}

(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);  
==> json is {"value1":,"value2":"abc"}

Note that you can not serialize objects with circular references since that will result in infinite recursion. 

(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);   
==> obj2 is just like obj
           

总结

至此异步网络请求并序列化为对象的官方方案都讨论完了,但是在实践中大家都不这么干……所以你也没看到实际的示例代码,下一篇咱们讨论一下在实践中大家的实现方案。