学习资料
Retrofit当前比较成熟的网络框架,可以与okhttp,Rxjava,这些框架协作,简化代码
资料来源
Retrofit的练习(看完这个自己可以写出一个简单的Retrofit实例来)
https://blog.csdn.net/carson_ho/article/details/73732076
Retrofit与Rxjava的协作(看完这个,可以用rxjava代替call,实现Rxjava的线程切换和UI的异步更新)
实现rxjava的轮询和网络回调,断线重连等操作等等实际开发场景
https://blog.csdn.net/carson_ho/article/details/79125101
Retrofit和okhttp(两篇文章,一个是如何设置okhttp,另一个是如何持久化管理cokie,实现免登陆的功能)
https://blog.csdn.net/lyhhj/article/details/51388147
http://blog.csdn.net/lyhhj/article/details/51345386
上面都是大神的学习资料,下面是我的实践记录
实现的基本步骤
步骤1:添加Retrofit库的依赖
步骤2:创建 接收服务器返回数据 的类
步骤3:创建 用于描述网络请求 的接口
步骤4:创建 Retrofit 实例
步骤5:创建 网络请求接口实例 并 配置网络请求参数
步骤6:发送网络请求(异步 / 同步)
一 实现一个简单的Retrofit实例
1 添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
Retrofit是默认通过okhttp实现的,关联了Retrofit项目,会自动引入okhttp的项目
2 创建 接收服务器返回数据 的类
Retrofit默认接受的到的数据时ResponseBody类型,如果不希望对body进行处理,省略第三步,直接跳转第四步
如果接受到的数据时json格式,希望在接受后自动转化,可以在创建实例的时候,添加Gson转化工厂
例如,我实现一个数据类
public class MyContact {
}
下面看第三步
3 创建 用于描述网络请求 的接口
public interface Api {
@POST("login/login")
@FormUrlEncoded
Call<ResponseBody> postLogin(@Field("account") String account, @Field("password") String password);
@POST("emp/txl")
@FormUrlEncoded
Call<List<MyContact>> postContact(@Field("empName") String empName);
@POST("login/logOut")
Call<ResponseBody> postInfo();
}
实现了三个方法
Call<ResponseBody>和Call<List<MyContact>>
意味着调用这个方法,返回的数据类型分别是默认的ResponseBody和List<MyContact>
网络请求注解 @post注解,表示这个方法会调用okhttp的post请求,()中的部分,是会与Retrofit.baseUrl组合连接,生成真正的Url对象
标记 @FormUrlEncoded 表示请求体是一个表单,键值对参数需要添加@Field注解.此外,@Multipart,可以上传文件,需要用@part标记{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型.参数中至少要包含okhttp3.MultipartBody.Part
参数@Field("key") String value 标记这个参数是一个键值对,等同于,"key"-value.与@Query的区别在于,@query会把参数加入到Url中,@Field会把参数放在请求体内.另外,@FormUrlEncoded 指定需要@Field来标记键值对
更多的注解使用参考文章开头的资料
4 创建 Retrofit 实例
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://192.168.1.18/venusApp/")
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
数据解析器
需要引入与Retrofit同一个版本的解析器
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
网络请求适配器,可以配合Rxjava,将Call转化成Observerble对象,引入Rxjava框架
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0'
5 创建 网络请求接口实例 并 配置网络请求参数
Api service =retrofit.create(Api.class);
Call<ResponseBody> call=service.postLogin("10317652","123456");
Call<List<MyContact>> call=service.postContact("xxx");
Call<ResponseBody> call=service.postInfo();
6 发送网络请求(异步 / 同步)
由于默认的实现是okhttp
我们通过上面的步骤获得了一个okhttp.Call
下面的使用就是Okhttp的知识
//同步
Response response=call.execute();
//异步
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()){
...//do something
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
二 实现Retrofit与Rxjava的结合
1 添加Retrofit库的依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
//网络请求适配器
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//这个是Rxjava1.0的适配器
//implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0'
//Rxjava
implementation 'io.reactivex.rxjava2:rxjava:2.1.16'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
2 创建 接收服务器返回数据 的类
还是MyContact
3 创建 用于描述网络请求 的接口
@POST("emp/txl")
@FormUrlEncoded
io.reactivex.Observable<List<MyContact>> postContact(@Field("empName") String empName);
4 创建 Retrofit 实例
retrofit=new Retrofit.Builder()
.baseUrl("http://192.168.1.18/venusApp/")
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
5 创建 网络请求接口实例 并 配置网络请求参数
Observable<List<MyContact>> observable=service.postContact(null);
6 发送网络请求(异步 / 同步)
这里就是调用Rxjava来配置了
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<MyContact>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List<MyContact> myContacts) {
StringBuilder temp= new StringBuilder();
for (MyContact data :
myContacts) {
temp.append(data.getEmpName());
}
textView.setText(temp);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
三 封装返回一个单例的Retrofit实例
public class RetrofitClient {
private static Retrofit retrofit;
private static OkHttpClient client;
private static final String TAG = "RetrofitClient";
//配置一个保存有cookie的Okhttp.Client
public static OkHttpClient getClient(){
if (client==null){
synchronized (OkHttpClient.class){
if (client==null){
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
client=new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
private HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.scheme(), cookies);
Log.i(TAG, "saveFromResponse: cookies="+cookies);
Log.i(TAG, "saveFromResponse:url.scheme()="+url.scheme());
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.scheme());
Log.i(TAG, "loadForRequest: cookies="+cookies);
Log.i(TAG, "loadForRequest: url.scheme()="+url.scheme());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.addInterceptor(logging)
.build();
}
}
}
return client;
}
//单例模式返回一个Retrofit实例
public static Retrofit getRetrofit(){
if (retrofit==null){
synchronized (Retrofit.class){
if (retrofit==null){
retrofit=new Retrofit.Builder()
.baseUrl("http://192.168.1.18/venusApp/")
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
}
}
Log.i(TAG, "getRetrofit: client="+getClient());
return retrofit;
}
}