一.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输入上方的包文件即可
添加网络权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
2.创建接口设置请求类型与参数
新建TestModel类(服务端返回的实体对象)和TestService接口样例如下
@GET("login") public Call<UserInfoModel> login(@Query("username")String username,@Query("pwd")String pwd);
常见参数注解
@GET、@POST
确定请求方式@Path
请求URL的字符替代@Query
要传递的参数@QueryMap
包含多个@Query注解参数@Body
添加实体类对象@FormUrlEncoded
URL编码
3.创建Retrofit对象、设置数据解析器
Retrofit retrofit = new Retrofit.Builder().baseUrl(Constants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
4.生成接口对象
TestService service = retrofit.create(TestService.class);
5.调用接口方法返回Call对象
Call<TestModel>call = 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<TestModel> test(); @POST("Ui-Gui/test/post") @FormUrlEncoded public Call<TestModel> testpost(@Field("testname")String testname); @PUT("Ui-Gui/test/put/{name}") public Call<TestModel> testput(@Path("name") String name); @DELETE("Ui-Gui/test/delete/{name}") public Call<TestModel> testdelete(@Path("name") String name); }
MainActivity的布局文件
<?xml version="1.0" encoding="utf-8"?> <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<TestModel> call = service.test(); //发送同步请求 // new Thread(new Runnable() { // @Override // public void run() { // Response<TestModel>response = null; // try { // response = call.execute(); // } catch (IOException e) { // e.printStackTrace(); // } // System.out.println(response.body()); // } // }).start(); //发布异步请求 call.enqueue(new Callback<TestModel>() { @Override public void onResponse(Call<TestModel> call, Response<TestModel> response) { System.out.println(response.body()); } @Override public void onFailure(Call<TestModel> 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<TestModel> call = service.testpost("this is post"); //发布异步请求 call.enqueue(new Callback<TestModel>() { @Override public void onResponse(Call<TestModel> call, Response<TestModel> response) { System.out.println(response.body()); } @Override public void onFailure(Call<TestModel> 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<TestModel> call = service.testput("putResult"); //发布异步请求 call.enqueue(new Callback<TestModel>() { @Override public void onResponse(Call<TestModel> call, Response<TestModel> response) { System.out.println(response.body()); } @Override public void onFailure(Call<TestModel> 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<TestModel> call = service.testdelete("this is what I want delete"); //发布异步请求 call.enqueue(new Callback<TestModel>() { @Override public void onResponse(Call<TestModel> call, Response<TestModel> response) { System.out.println(response.body()); } @Override public void onFailure(Call<TestModel> call, Throwable t) { } }); } }
四.内容总结
- Retrofit是基于Okhttp网络库的高级封装
- 采用注解、网络请求参数配置更灵活、扩展性更好
- RESTful风格的API优先选用Retrofit