終於到了網絡請求模塊了。由於之前一直使用的都是Okhttp,因此此次使用Retrofit的話花了兩天時間去了解。總的來講Retrofit就是初始化搭建麻煩,挺多東西要注意的。不過看到各界大佬一致好評的請求框架,苦點就苦點。java
走過路過點歌Start O(∩_∩)O Github項目地址react
這篇文章叫你如何搭建MVP+Retrofit+Rxjava,看完這篇文章你能學會:android
目錄: Retrofit使用思路git
Retrofit 如何結合Rxjava Retrofit+Rxjava如何結合Mvpgithub
總體的思路其實跟OKhttp仍是很類似的。 初始化環境:api
/*
* 靜態模式
* */
public class RetrofitUtil {
/*
* BaseUrl
* */
private final static String BASE_URL = "http://v.juhe.cn/";
private static Retrofit mRetrofit;
private static RetrofitUtil mRetrofitUtil;
static {
mRetrofitUtil = new RetrofitUtil();
initRetrofit();
}
private RetrofitUtil () {
}
public static RetrofitUtil newInstance() {
return mRetrofitUtil;
}
/*
* 初始化網絡設置
* */
private static void initRetrofit () {
// 設置okhttp
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(6000, TimeUnit.SECONDS)//設置超時時間
.retryOnConnectionFailure(true);
//添加攔截
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
builder.addInterceptor(logInterceptor);
OkHttpClient client = builder.build();
//設置retrofit
mRetrofit = new Retrofit
.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
/*
* 建立api
* */
public <T> T createApi (Class<T> cla) {
return mRetrofit.create(cla);
}
}
複製代碼
用了單例模式,這裏暫時還沒作不少通用的一些處理。完成這一步以後等於Retrofit的環境已經建立好了。這個時候就要開始定義具體的請求,經過這個retrofit對象來發起。接着看: 這裏要注意的是:BASE_URL但是有要求的,不能隨便寫;例如後面的路徑不能追加在這裏。bash
忘記貼依賴包了:按需添加網絡
// 網絡請求 Retrofit + Rxjava
implementation 'com.squareup.retrofit2:retrofit:2.3.0'//導入retrofit
implementation 'com.google.code.gson:gson:2.6.2'//Gson 庫
implementation 'com.squareup.okhttp3:okhttp:3.1.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.1.2'
implementation 'com.orhanobut:logger:2.1.0' // 打印日誌
//下面兩個是RxJava 和 RxAndroid
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.x.y'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//轉換器,請求結果轉換成Model
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'//配合Rxjava
複製代碼
定義API接口:app
public interface Api {
//http://v.juhe.cn/toutiao/index?type=top&key=APPKEY
@GET("/toutiao/index")
Observable<NewsDomain> getNews (@Query("type")String type, @Query("key")String apiKey);
}
複製代碼
這些註解的用法使得代碼很簡潔,只須要多看看官網/教程就知道怎麼用了。框架
實例化API
public class TestModel implements ITest {
private static final String TAG = "bigname";
@Override
public Observable<NewsDomain> test() {
RetrofitUtil retrofitUtil = RetrofitUtil.newInstance();
Api api = retrofitUtil.createApi(Api.class);
return api.getNews("top", "dc4fed8fb5fb46ac78e51d66306e6762");
}
}
複製代碼
到這裏,應用就可以發起請求了。
處理請求響應
public class MainPresenter extends MainContract.MainPresenter {
private static final String TAG = "bigname";
@Override
public void login(String name, String password) {
TestModel testModel = new TestModel();
Observable<NewsDomain> newsDomainObservable = testModel.test();
newsDomainObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<NewsDomain>() {
@Override
public void onNext(NewsDomain newsDomain) {
Log.d(TAG, "onNext: " + newsDomain.toString());
mView.showTips(newsDomain.getReason());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
}
});
}
}
複製代碼
就是這麼簡單。 看看效果:
若是出現報錯:java.net.UnknownServiceException 這是由於API28開始網絡請求更加嚴格引發的,解決方法: 1.在res目錄下新建xml資源,而後建立network_security_config.xml文件, 內容:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
複製代碼
2.在清單文件中:
<application
android:networkSecurityConfig="@xml/network_security_config"
複製代碼
這樣就解決了。
------------------------------------人工分割-------------------------------------------
這個我剛開始覺得還多麻煩呢。 Retrofit嵌入Rxjava只需簡單幾步:
依賴就不貼圖了, retrofit對rxjava支持:
mRetrofit = new Retrofit
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
複製代碼
要注意的是Rxjava2CallAdapterFactroy()在依賴版本方面須要注意,要對應的。 請求響應從Call變成Obserable
@GET("/toutiao/index")
Observable<NewsDomain> getNews (@Query("type")String type, @Query("key")String apiKey);
複製代碼
若是不適用Rxjava,則返回Call對象,這種方式同樣能實現功能。
-------------------------------------------人工分割線---------------------------------------------------
簡單到真的不必打字的感受。傳統的方式是構造ICallBack傳遞給Model層,而後利用接口回調的方式,如今這種是Model層會返回Obserable觀察者對象,Presenter層拿到這個Obserable對象以後把他當成CallBack對象來使用就好了。
Observable<NewsDomain> newsDomainObservable = testModel.test();
newsDomainObservable.subscribeOn(Schedulers.io())...
複製代碼
The end...