Retrofit:基于OkHttp的RESTful风格API的网络框架封装

一.Retrofit介绍

  • Retrofit是Square公司基于RESTful风格推出的网络框架封装
  • Retrofit与OKHttp的关系:Retrofit是基于OKHttp的网络请求框架的二次封装,其本质仍是OKHttp
  • 与其他网络库的对比
    • AndroidAsynHttp:基于HttpClient,作者停止维护,Android5.0不再使用HttpClient,因此不推荐
    • Volley:基于HttpUrlConnection,Google官方推出,只适合轻量级网络交互如数据传输小,不适合大文件下上传场景
    • Retrofit优点:API设计简洁易用、注解化配置高度解耦、支持多种解析器、支持Rxjava

二.Retrofit使用

1.开源库集成

  • 依赖包导入:
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
  • 导入方式:

    File -> project structure -> app -> dependencies -> 左下方有一个加号,点击选择Library dependency输入上方的包文件即可

  • 添加网络权限:

2.创建接口设置请求类型与参数

  • 新建TestModel类(服务端返回的实体对象)和TestService接口样例如下

    @GET("login")
    public Call login(@Query("username")String username,@Query("pwd")String pwd);
  • 常见参数注解

    • @GET、@POST确定请求方式
    • @Path请求URL的字符替代
    • @Query要传递的参数
    • @QueryMap包含多个@Query注解参数
    • @Body添加实体类对象
    • @FormUrlEncodedURL编码

3.创建Retrofit对象、设置数据解析器

Retrofit retrofit = new Retrofit.Builder().baseUrl(Constants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();

4.生成接口对象

TestService service = retrofit.create(TestService.class);

5.调用接口方法返回Call对象

Callcall = service.login("zhangsan","123456");

6.发送请求(同步、异步)

  • 同步:调用Call对象的execute(),返回结果的响应体(默认将代码放入主线程,而安卓4.0后不允许在主线程中执行耗时操作,故应新建一个线程,将请求代码放入)
  • 异步:调用Call对象的enqueue(),参数是一个Callback回调函数

7.处理返回的数据

三.Retrofit案例

  • 服务端采用SSM框架写的controller层用于测试接口与返回数据

    package controller.admin;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    @Controller
    @RequestMapping("/test")
    public class testController {
    @ResponseBody
    @RequestMapping(value="/get",method=RequestMethod.GET)
    public ReturnObject testGet() {
        ReturnObject ro = new ReturnObject(true,"test");
        return ro;
    }
    
    @ResponseBody
    @RequestMapping(value="/post",method=RequestMethod.POST)
    public ReturnObject testPost(@RequestParam("testname")String testname) {
        ReturnObject ro = new ReturnObject(true,testname);
        return ro;
    }
    
    @ResponseBody
    @RequestMapping(value="/put/{name}",method=RequestMethod.PUT)
    public ReturnObject testPut(@PathVariable("name")String testname) {
        ReturnObject ro = new ReturnObject(true,testname);
        return ro;
    }
    
    @ResponseBody
    @RequestMapping(value="/delete/{name}",method=RequestMethod.DELETE)
    public ReturnObject testDelete(@PathVariable("name")String testname) {
        ReturnObject ro = new ReturnObject(true,testname);
        return ro;
    }
    }
    
    class ReturnObject{
    private boolean status;
    private String info;
    public boolean isStatus() {
        return status;
    }
    public void setStatus(boolean status) {
        this.status = status;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    @Override
    public String toString() {
        return "ReturnObject [status=" + status + ", info=" + info + "]";
    }
    public ReturnObject(boolean status, String info) {
        super();
        this.status = status;
        this.info = info;
    }
    }
  • 创建Contants类,定义访问主机及端口号

    package c.e.retrofittest;
    public class Contants {
      public static String BASE_URL = "http://192.168.1.104:8080/";
    }
  • 定义TestModel实体类

    package c.e.retrofittest;
    public class TestModel {
      private boolean status;
      private String info;
      public boolean isStatus() {
          return status;
      }
      public void setStatus(boolean status) {
          this.status = status;
      }
      public String getInfo() {
          return info;
      }
      public void setInfo(String info) {
          this.info = info;
      }
      @Override
      public String toString() {
          return "TestModel{" +
                  "status=" + status +
                  ", info='" + info + '\'' +
                  '}';
      }
    }
  • 定义TestService请求接口【注意:POST请求必须加入@FormUrlEncoded注解,且请求体中内容字段用@Field修饰;GET请求参数用@Query修饰;PUT和DELETE请求URL上的参数用@Path修饰】

    package c.e.retrofittest;
    
    import retrofit2.Call;
    import retrofit2.http.DELETE;
    import retrofit2.http.Field;
    import retrofit2.http.FormUrlEncoded;
    import retrofit2.http.GET;
    import retrofit2.http.POST;
    import retrofit2.http.PUT;
    import retrofit2.http.Part;
    import retrofit2.http.Path;
    import retrofit2.http.Query;
    
    public interface TestService {
    
      @GET("Ui-Gui/test/get")
      public Call test();
    
      @POST("Ui-Gui/test/post")
      @FormUrlEncoded
      public Call testpost(@Field("testname")String testname);
    
      @PUT("Ui-Gui/test/put/{name}")
      public Call testput(@Path("name") String name);
    
      @DELETE("Ui-Gui/test/delete/{name}")
      public Call testdelete(@Path("name") String name);
    }
    
  • MainActivity的布局文件

    
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      tools:context="c.e.retrofittest.MainActivity">
    
      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="GET"
          android:onClick="onAction"/>
    
      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="POST"
          android:onClick="onPost"/>
    
      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="PUT"
          android:onClick="onPut"/>
    
      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="DELETE"
          android:onClick="onDelete"/>
    LinearLayout>
  • 在MainActivity中执行对应发送请求的步骤

    package c.e.retrofittest;
    
    import android.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    
    import junit.framework.Test;
    
    import java.io.IOException;
    
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    import retrofit2.Retrofit;
    import retrofit2.converter.gson.GsonConverterFactory;
    
    public class MainActivity extends AppCompatActivity {
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
      }
    
      public void onAction(View view) throws IOException {
          //创建Retrofit对象
          Retrofit retrofit = new Retrofit.Builder().baseUrl(Contants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
          //生成接口对象
          TestService service = retrofit.create(TestService.class);
          //调用接口方法返回Call对象
          final Call call = service.test();
          //发送同步请求
    //        new Thread(new Runnable() {
    //            @Override
    //            public void run() {
    //                Responseresponse = null;
    //                try {
    //                    response = call.execute();
    //                } catch (IOException e) {
    //                    e.printStackTrace();
    //                }
    //                System.out.println(response.body());
    //            }
    //        }).start();
          //发布异步请求
          call.enqueue(new Callback() {
              @Override
              public void onResponse(Call call, Response response) {
                  System.out.println(response.body());
              }
    
              @Override
              public void onFailure(Call call, Throwable t) {
    
              }
          });
      }
    
      public void onPost(View view) throws IOException {
          //创建Retrofit对象
          Retrofit retrofit = new Retrofit.Builder().baseUrl(Contants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
          //生成接口对象
          TestService service = retrofit.create(TestService.class);
          //调用接口方法返回Call对象
          final Call call = service.testpost("this is post");
          //发布异步请求
          call.enqueue(new Callback() {
              @Override
              public void onResponse(Call call, Response response) {
                  System.out.println(response.body());
              }
    
              @Override
              public void onFailure(Call call, Throwable t) {
    
              }
          });
      }
    
      public void onPut(View view) throws IOException {
          //创建Retrofit对象
          Retrofit retrofit = new Retrofit.Builder().baseUrl(Contants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
          //生成接口对象
          TestService service = retrofit.create(TestService.class);
          //调用接口方法返回Call对象
          final Call call = service.testput("putResult");
          //发布异步请求
          call.enqueue(new Callback() {
              @Override
              public void onResponse(Call call, Response response) {
                  System.out.println(response.body());
              }
    
              @Override
              public void onFailure(Call call, Throwable t) {
    
              }
          });
      }
    
      public void onDelete(View view) throws IOException {
          //创建Retrofit对象
          Retrofit retrofit = new Retrofit.Builder().baseUrl(Contants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
          //生成接口对象
          TestService service = retrofit.create(TestService.class);
          //调用接口方法返回Call对象
          final Call call = service.testdelete("this is what I want delete");
          //发布异步请求
          call.enqueue(new Callback() {
              @Override
              public void onResponse(Call call, Response response) {
                  System.out.println(response.body());
              }
    
              @Override
              public void onFailure(Call call, Throwable t) {
    
              }
          });
      }
    }

四.内容总结

  • Retrofit是基于Okhttp网络库的高级封装
  • 采用注解、网络请求参数配置更灵活、扩展性更好
  • RESTful风格的API优先选用Retrofit

你可能感兴趣的:(Android相关)