目录
一、简介
二、Retrofit基本使用
(1)在build文件中加入相关依赖
(2)基本使用
(3)测试
三、Retrofit 自定义的OkHttpClient
(1)设置自定义的OkHttpClient
(2)Retrofit 添加client
(3)打印效果
四、Retrofit 与 Rxjava 结合使用
(1)添加依赖
(2)Retrofit 设置
(3)其他修改
(4)测试结果
五、防止Rxjava引发的内存泄漏
(1)添加依赖
(2)基本使用
六、总结与封装
七、Demo地址
八、内容推荐
前言
这是第二次改编、之前第一次写这篇博客的时候只是当成笔记记录一下。都没有怎么仔细介绍内容,可能导致一些朋友们没看明白,这次重新组织一下。当然由于内容比较多,不可能太详细。我尽量做到让更多人能够看明白,哈哈 当然 朋友们也要跟着我的步骤一步一步来实现 ,这样会比较好理解。
一、简介
大家都知道Retrofit是对OKHttp的第二次封装,使用上也比较简单。那为什么还要对Retrofit进行封装呢,个人理解主要还是对Retrofit进行更规范的分类,有利于项目的开发与维护,提高网络请求这一块的效率。好了,可以开始跟我走了。。一步一步的走向巅峰,然后再回头来听我吹牛逼。。
二、Retrofit基本使用
(1)在build文件中加入相关依赖
//github地址:https://github.com/square/retrofit
//文档地址:https://square.github.io/retrofit/
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
(2)基本使用
public interface ApiUrl {
//get请求
@GET(Constans.retrofit)
Call<Bean> getRetrofit();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constans.BaseUrl)
.build();
ApiUrl api = retrofit.create(ApiUrl.class);
Call<Bean> demo = api.getRetrofit();
demo.enqueue(new Callback<Bean>() {
@Override
public void onResponse(Call<Bean> call, Response<Bean> response) {
Log.e(TAG, "请求成功信息: "+response.body().toString());
}
@Override
public void onFailure(Call<Bean> call, Throwable t) {
Log.e(TAG, "请求失败信息: " +t.getMessage());
}
});
目前大部分后台一般会返回JSON数据类型所以我们需要Retrofit 添加JSON支持
//retrofit添加Json解析返回数据
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constans.BaseUrl)
//添加GSON解析:返回数据转换成GSON类型
.addConverterFactory(GsonConverterFactory.create())
.build();
这样就可以解析JSON数据
(3)测试
这里提供测试Url,返回的是JSON数据类型
public final static String BaseUrl = "http://120.78.186.81/api/";
public final static String retrofit = "values/5";
映射返回数据
/**
* {
* "res_code": 200,
* "err_msg": "Web page does not exist",
* "demo": {
* "id": "1001",
* "appid": "1021",
* "name": "sss",
* "showtype": "text"
* }
* }
*/
public class Bean {
@Override
public String toString() {
return "bean{" +
"res_code=" + res_code +
", err_code=" + err_code +
", err_msg='" + err_msg + '\'' +
", demo=" + demo +
'}';
}
private int res_code;
private int err_code;
private String err_msg;
private DemoBean demo;
public int getRes_code() {
return res_code;
}
public void setRes_code(int res_code) {
this.res_code = res_code;
}
public int getErr_code() {
return err_code;
}
public void setErr_code(int err_code) {
this.err_code = err_code;
}
public String getErr_msg() {
return err_msg;
}
public void setErr_msg(String err_msg) {
this.err_msg = err_msg;
}
public DemoBean getDemo() {
return demo;
}
public void setDemo(DemoBean demo) {
this.demo = demo;
}
public static class DemoBean {
@Override
public String toString() {
return "DemoBean{" +
"id='" + id + '\'' +
", appid='" + appid + '\'' +
", name='" + name + '\'' +
", showtype='" + showtype + '\'' +
'}';
}
private String id;
private String appid;
private String name;
private String showtype;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShowtype() {
return showtype;
}
public void setShowtype(String showtype) {
this.showtype = showtype;
}
}
}
发送请求并打印返回数据
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constans.BaseUrl)
//添加GSON解析
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiUrl api = retrofit.create(ApiUrl.class);
Call<Bean> demo = api.getRetrofit();
demo.enqueue(new Callback<Bean>() {
@Override
public void onResponse(Call<Bean> call, Response<Bean> response) {
Log.e(TAG, "请求成功信息: "+response.body().toString());
}
@Override
public void onFailure(Call<Bean> call, Throwable t) {
Log.e(TAG, "请求失败信息: " +t.getMessage());
}
});
别忘了——添加网络权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
打印结果:
E/RetrofitActivity: 请求成功信息: bean{res_code=200, err_code=0, err_msg='Web page does not exist', demo=DemoBean{id='1001', appid='1021', name='sss', showtype='text'}}
三、Retrofit 自定义的OkHttpClient
这里介绍一些常用的设置
(1)设置自定义的OkHttpClient
OkHttpClient client = new OkHttpClient().newBuilder()
.readTimeout(Constans.DEFAULT_TIME, TimeUnit.SECONDS)//设置读取超时时间
.connectTimeout(Constans.DEFAULT_TIME, TimeUnit.SECONDS)//设置请求超时时间
.writeTimeout(Constans.DEFAULT_TIME,TimeUnit.SECONDS)//设置写入超时时间
.addInterceptor(new LogInterceptor())//添加打印拦截器
.retryOnConnectionFailure(true)//设置出现错误进行重新连接。
.build();
//设置默认超时时间
public static final int DEFAULT_TIME=10;
/**
* TODO Log拦截器代码
*/
import android.util.Log;
import java.io.IOException;
import java.util.Locale;
import okhttp3.Interceptor;
import okhttp3.Request;
/**
* TODO Log拦截器代码
*/
public class LogInterceptor implements Interceptor {
private String TAG = "okhttp";
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
// .newBuilder()
// .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
// .addHeader("Accept-Encoding", "gzip, deflate")
// .addHeader("Connection", "keep-alive")
// .addHeader("Accept", "*/*")
// .addHeader("Cookie", "add cookies here")
// .build()
;
Log.e(TAG,"request:" + request.toString());
long t1 = System.nanoTime();
okhttp3.Response response = chain.proceed(chain.request());
long t2 = System.nanoTime();
Log.e(TAG,String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
okhttp3.MediaType mediaType = response.body().contentType();
String content = response.body().string();
Log.e(TAG, "response body:" + content);
return response.newBuilder()
.body(okhttp3.ResponseBody.create(mediaType, content))
// .header("Authorization", Your.sToken)
.build();
}
}
(2)Retrofit 添加client
Retrofit retrofit = new Retrofit.Builder()
//设置自定义okHttp
.client(client)
.baseUrl(Constans.BaseUrl)
//添加GSON解析
.addConverterFactory(GsonConverterFactory.create())
.build();
(3)打印效果
E/okhttp: request:Request{method=GET, url=http://pndatsn5v.bkt.clouddn.com/retrofit.txt, tags={class retrofit2.Invocation=retrofit.interfaces.ApiUrl.getRetrofit() []}}
E/okhttp: Received response for http://pndatsn5v.bkt.clouddn.com/retrofit.txt in 55.1ms
Server: Tengine
Content-Type: text/plain
Connection: keep-alive
Date: Sat, 23 Feb 2019 08:17:35 GMT
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Log, X-Reqid
Access-Control-Max-Age: 2592000
Cache-Control: public, max-age=31536000
Content-Disposition: inline; filename="retrofit.txt"; filename*=utf-8' 'retrofit.txt
Content-Transfer-Encoding: binary
Etag: "Fh65gSkYd4KepQbHi-rWZDlhKjmO.gz"
Last-Modified: Sat, 23 Feb 2019 08:14:42 GMT
Vary: Accept-Encoding
X-Log: AC;CFGG:4;redis.g/404;redis.g;rs5_shard.sel:2;rwro.get:2;RS.dbs:2;RS:3;redis.s;2s.gh;PFDS;AUTHPROXY_dg_out;IO:85
X-M-Log: QNM:xs1172;QNM3
X-M-Reqid: dGUAAMyobctL8IUV
X-Qiniu-Zone: 2
X-Qnm-Cache: Hit
X-Reqid: EkMAAA7s1xso8IUV
X-Svr: IO
Ali-Swift-Global-Savetime: 1550909855
Via: cache4.l2et15[10,200-0,M], cache15.l2et15[11,0], vcache19.cn1177[0,200-0,H], vcache2.cn1177[1,0]
Age: 80679
X-Cache: HIT TCP_MEM_HIT dirn:2:55209266
X-Swift-SaveTime: Sat, 23 Feb 2019 08:17:35 GMT
X-Swift-CacheTime: 2592000
Timing-Allow-Origin: *
EagleId: 1b9f47ca15509905340914033e
E/okhttp: response body:{
"res_code": 200,
"err_msg": "Web page does not exist",
"demo": {
"id": "1001",
"appid": "1021",
"name": "sss",
"showtype": "text"
}
}
E/RetrofitActivity: 请求成功信息: bean{res_code=200, err_code=0, err_msg='Web page does not exist', demo=DemoBean{id='1001', appid='1021', name='sss', showtype='text'}}
四、Retrofit 与 Rxjava 结合使用
(1)添加依赖
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
(2)Retrofit 设置
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(Constans.BaseUrl)
//添加GSON解析:返回数据转换成GSON类型
.addConverterFactory(GsonConverterFactory.create())
//添加Rxjava支持
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
(3)其他修改
//@GET(Constans.retrofit)
//Call<Bean> getRetrofit();
@GET(Constans.retrofit)
Observable<Bean> getRetrofit1();
retrofit.create(ApiUrl.class)
.getRetrofit1()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Bean>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: " );
}
@Override
public void onNext(Bean demo) {
Log.e(TAG, "onNext: " +demo.toString());
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "Throwable: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: " );
}
});
(4)测试结果
E/RetrofitActivity: onSubscribe:
E/RetrofitActivity: onNext: bean{res_code=200, err_code=0, err_msg='Web page does not exist', demo=DemoBean{id='1001', appid='1021', name='sss', showtype='text'}}
E/RetrofitActivity: onComplete:
五、防止Rxjava引发的内存泄漏
当使用
RxJava
订阅并执行耗时任务后,当Activity
被finish
时,如果耗时任务还未完成,没有及时取消订阅,就会导致Activity
无法被回收,从而引发内存泄漏。为了解决这个问题,就产生了RxLifecycle
,让RxJava
变得有生命周期感知,使得其能及时取消订阅,避免出现内存泄漏问题。
(1)添加依赖
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
(2)基本使用
Activity 需继承自 RxAppCompatActivity 或 RxFragmentActivity 或 RxActivity
Fragment 需继承 RxFragment
retrofit.create(ApiUrl.class)
.getRetrofit1()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//绑定生命周期
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new Observer<Bean>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: " );
}
@Override
public void onNext(Bean demo) {
Log.e(TAG, "onNext: " +demo.toString());
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "Throwable: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: " );
}
});
好了 目前了解这些已经够用了 不过直接使用还是很麻烦,重复代码比较多 。所以需要进行整理和封装
六、总结与封装
《Android Rxjava+Retrofit网络请求框架封装(二)》
七、Demo地址
https://github.com/DayorNight/RxjavaRetrofit2
八、内容推荐
如果你觉得我写的不错或者对您有所帮助的话
不妨顶一个【微笑】,别忘了点赞、收藏、加关注哈
看在我花了这么多时间整理写成文章分享给大家的份上,记得手下留情哈
您的每个举动都是对我莫大的支持