目錄
一弦聂、簡介
二鸟辅、Retrofit基本使用
(1)在build文件中加入相關(guān)依賴
(2)基本使用
(3)測試
三、Retrofit 自定義的OkHttpClient
(1)設(shè)置自定義的OkHttpClient
(2)Retrofit 添加client
(3)打印效果
四莺葫、Retrofit 與 Rxjava 結(jié)合使用
(1)添加依賴
(2)Retrofit 設(shè)置
(3)其他修改
(4)測試結(jié)果
五匪凉、防止Rxjava引發(fā)的內(nèi)存泄漏
(1)添加依賴
(2)基本使用
六、總結(jié)與封裝
七捺檬、Demo地址
八洒缀、內(nèi)容推薦
前言
這是第二次改編、之前第一次寫這篇博客的時(shí)候只是當(dāng)成筆記記錄一下欺冀。都沒有怎么仔細(xì)介紹內(nèi)容树绩,可能導(dǎo)致一些朋友們沒看明白,這次重新組織一下隐轩。當(dāng)然由于內(nèi)容比較多饺饭,不可能太詳細(xì)。我盡量做到讓更多人能夠看明白职车,哈哈 當(dāng)然 朋友們也要跟著我的步驟一步一步來實(shí)現(xiàn) 瘫俊,這樣會比較好理解。
一悴灵、簡介
大家都知道Retrofit是對OKHttp的第二次封裝扛芽,使用上也比較簡單。那為什么還要對Retrofit進(jìn)行封裝呢积瞒,個(gè)人理解主要還是對Retrofit進(jìn)行更規(guī)范的分類川尖,有利于項(xiàng)目的開發(fā)與維護(hù),提高網(wǎng)絡(luò)請求這一塊的效率茫孔。好了叮喳,可以開始跟我走了被芳。。一步一步的走向巔峰馍悟,然后再回頭來聽我吹牛逼畔濒。。
二锣咒、Retrofit基本使用
(1)在build文件中加入相關(guān)依賴
//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數(shù)據(jù)類型所以我們需要Retrofit 添加JSON支持
//retrofit添加Json解析返回?cái)?shù)據(jù)
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constans.BaseUrl)
//添加GSON解析:返回?cái)?shù)據(jù)轉(zhuǎn)換成GSON類型
.addConverterFactory(GsonConverterFactory.create())
.build();
這樣就可以解析JSON數(shù)據(jù)
(3)測試
這里提供測試Url,返回的是JSON數(shù)據(jù)類型
public final static String BaseUrl = "http://120.78.186.81/api/";
public final static String retrofit = "values/5";
映射返回?cái)?shù)據(jù)
/**
* {
* "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;
}
}
}
發(fā)送請求并打印返回?cái)?shù)據(jù)
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());
}
});
別忘了——添加網(wǎng)絡(luò)權(quán)限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
打印結(jié)果:
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
這里介紹一些常用的設(shè)置
(1)設(shè)置自定義的OkHttpClient
OkHttpClient client = new OkHttpClient().newBuilder()
.readTimeout(Constans.DEFAULT_TIME, TimeUnit.SECONDS)//設(shè)置讀取超時(shí)時(shí)間
.connectTimeout(Constans.DEFAULT_TIME, TimeUnit.SECONDS)//設(shè)置請求超時(shí)時(shí)間
.writeTimeout(Constans.DEFAULT_TIME,TimeUnit.SECONDS)//設(shè)置寫入超時(shí)時(shí)間
.addInterceptor(new LogInterceptor())//添加打印攔截器
.retryOnConnectionFailure(true)//設(shè)置出現(xiàn)錯(cuò)誤進(jìn)行重新連接。
.build();
//設(shè)置默認(rèn)超時(shí)時(shí)間
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()
//設(shè)置自定義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 結(jié)合使用
(1)添加依賴
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
(2)Retrofit 設(shè)置
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(Constans.BaseUrl)
//添加GSON解析:返回?cái)?shù)據(jù)轉(zhuǎn)換成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)測試結(jié)果
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引發(fā)的內(nèi)存泄漏
當(dāng)使用
RxJava
訂閱并執(zhí)行耗時(shí)任務(wù)后,當(dāng)Activity
被finish
時(shí)毛嫉,如果耗時(shí)任務(wù)還未完成诽俯,沒有及時(shí)取消訂閱,就會導(dǎo)致Activity
無法被回收承粤,從而引發(fā)內(nèi)存泄漏暴区。為了解決這個(gè)問題,就產(chǎn)生了RxLifecycle
辛臊,讓RxJava
變得有生命周期感知仙粱,使得其能及時(shí)取消訂閱,避免出現(xiàn)內(nèi)存泄漏問題彻舰。
(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: " );
}
});
好了 目前了解這些已經(jīng)夠用了 不過直接使用還是很麻煩伐割,重復(fù)代碼比較多 。所以需要進(jìn)行整理和封裝
六刃唤、總結(jié)與封裝
《Android Rxjava+Retrofit網(wǎng)絡(luò)請求框架封裝(二)》
七隔心、Demo地址
https://github.com/DayorNight/RxjavaRetrofit2
八、內(nèi)容推薦
如果你覺得我寫的不錯(cuò)或者對您有所幫助的話
不妨頂一個(gè)【微笑】尚胞,別忘了點(diǎn)贊硬霍、收藏、加關(guān)注哈
看在我花了這么多時(shí)間整理寫成文章分享給大家的份上笼裳,記得手下留情哈
您的每個(gè)舉動(dòng)都是對我莫大的支持