Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于Okhttp实现
compile 'com.squareup.retrofit2:retrofit:2.0.2'
一、retrofit用法示例
1、一般的get请求
retrofit在使用过程中,需要定义一个接口对象,接口如下所示:
public interface IUserBiz { @GET("users") Call<List<User>> getUsers(); }
可以看到有一个getUsers()方法,通过@GET注解标识为get请求,@GET中所填写的value和baseUrl组成完整的路径,baseUrl在构造retrofit对象是给出,下面看如何通过retrofit完成上述请求:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://192.168.31.242:8080/springmvc_users/user/") .addConverterFactory(GsonConverterFactory.create()) .build(); IUserBiz userBiz = retrofit.create(IUserBiz.class); Call<List<User>> call = userBiz.getUsers(); call.enqueue(new Callback<List<User>>() { @Override public void onResponse(Call<List<User>> call, Response<List<User>> response) { Log.e(TAG, "normalGet:" + response.body() + ""); } @Override public void onFailure(Call<List<User>> call, Throwable t) { } });
依然是构造者模式,指定了baseUrl和Converter.Factory,该对象通过名称可以看出是用于对象转化的,本利由于返回的是json格式的数组,所以设置了GsonConverterFactory完成对象转化。
通过Retrofit.create就可以拿到定义的IUserBiz的实例,调用其方法即可拿到一个Call对象,通过call.enqueue即可完成异步的请求。
这里需要指出的是:
- 接口中的方法必须有返回值,且必须是
Call<T>
类型 -
.addConverterFactory(GsonConverterFactory.create())
这里如果使用gson,需要额外导入:compile 'com.squareup.retrofit2:converter-gson:2.0.2'
当然除了gson以外,还提供了以下的选择:
Gson: com.squareup.retrofit2:converter-gson Jackson: com.squareup.retrofit2:converter-jackson Moshi: com.squareup.retrofit2:converter-moshi Protobuf: com.squareup.retrofit2:converter-protobuf Wire: com.squareup.retrofit2:converter-wire Simple XML: com.squareup.retrofit2:converter-simplexml Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
当然也支持自定义,你可以选择自己写转化器完成数据的转化,这个后面将具体介绍。
3.既然call.enqueue
是异步的访问数据,那么同步的访问方式为call.execute
,这一点非常类似okhttp的API,实际上默认情况下内部也是通过okhttp3.Call
实现。
二、动态的url访问@PATH
//用于访问zhy的信息 http://192.168.1.102:8080/springmvc_users/user/zhy //用于访问lmj的信息 http://192.168.1.102:8080/springmvc_users/user/lmj
public interface IUserBiz { @GET("{username}") Call<User> getUser(@Path("username") String username); }
可以看到我们定义了一个getUser方法,方法接收一个username参数,并且我们的@GET
注解中使用{username}
声明了访问路径,这里你可以把{username}
当做占位符,而实际运行中会通过@PATH("username")
所标注的参数进行替换。
//省略了retrofit的构建代码 Call<User> call = userBiz.getUser("zhy"); //Call<User> call = userBiz.getUser("lmj"); call.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { Log.e(TAG, "getUsePath:" + response.body()); } @Override public void onFailure(Call<User> call, Throwable t) { } });
三、查询参数的设置@Query
看下面的url
http://baseurl/users?sortby=username http://baseurl/users?sortby=id
即一般的传参,我们可以通过@Query注解方便地完成,在接口中添加一个方法:
public interface IUserBiz { @GET("users") Call<List<User>> getUsersBySort(@Query("sortby") String sort); }
//省略retrofit的构建代码 Call<List<User>> call = userBiz.getUsersBySort("username"); //Call<List<User>> call = userBiz.getUsersBySort("id"); //省略call执行相关代码
Retrofit实用
接口:
public interface RequestServes { @POST("sug") Call<String> getMsg(@Query("code") String code,//utf-8 @Query("q") String q,//关键字 @Query("callback") String callback); }
Client.java
public class Client { private static final long TIME_OUT = 5000; public static OkHttpClient create(){ OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS); builder.readTimeout(TIME_OUT,TimeUnit.SECONDS); builder.writeTimeout(TIME_OUT,TimeUnit.SECONDS); return builder.build(); } }
MyApplication.java
public class MyApplication extends Application { public static final String url = "http://suggest.taobao.com/"; public static RequestServes mInter; @Override public void onCreate() { super.onCreate(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(url) .client(Client.create()) //增加返回值为String的支持 .addConverterFactory(ScalarsConverterFactory.create()) //增加返回值为Gson的支持(以实体类返回) .addConverterFactory(GsonConverterFactory.create()) .build(); mInter = retrofit.create(RequestServes.class); } }
MainActivity.java
public class MainActivity extends AppCompatActivity { @BindView(R.id.tv) TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); Call<String> info = MyApplication.mInter.getMsg("utf-8","裙子", "cb"); info.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { Log.d("falg","info="+response.body()); tv.setText(response.body()); Toast.makeText(MainActivity.this, "成功了", Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<String> call, Throwable t) { Toast.makeText(MainActivity.this, "失败了", Toast.LENGTH_SHORT).show(); } }); } }