OKhttp、RXjava與retrofit的網路訪問使用
阿新 • • 發佈:2018-12-12
兩個月沒有寫微博了,無論如何,現在再次迴歸Android的打怪升級。
關於Rxjava的學習和介紹,有興趣的可以去雲盤中提取pdf資料,這裡不做詳解,地址和提取碼如下:連結:http://pan.baidu.com/s/1skDOjN3 密碼: ajv7。
要想Rxjava和Retrofit結合使用,我們先簡單瞭解一下什麼是Retrofit:Square提供的開源產品,為Android平臺的應用提供一個型別安全的REST客戶端。
只使用Retrofit來訪問網路: 1.準備:此處模擬網路返回的資料格式為JSON,這裡使用fastjson來做為解析工具(Android自帶的JSON解析工具功能沒有那麼強大,有可能會引發問題,不推薦使用)
2.Activity中設定點選事件,用於進行網路請求,請求地址和內容請自行配置,此處使用本人設定的地址和資料: private static final String ENDPOINT = "http://192.168.105.XXX:7072/TQA/API/MoblieAPI/"
case R.id.tv_retrofit: retrofitTest("78a5bcc7-0a97-44db-a430-0b1a1db422f2",this); //傳入UserID break;
3.API:網路請求的資料傳輸和方法
public interface ApiService {
@GET("GetUserInfo")
Call<JSONObject> getUserInfo(@Query("userId") String UserID);
}
4.DTO:資料儲存物件
public class ClassInfoDto implements Serializable { private String UserId; private String UserName; private String EchoName; private int Sex; private String Photo; private String Phone; private String WorkNo; //根據返回的資料設定資料儲存物件,此處省略GET和SET方法的程式碼 }
5.Retrofit實現方法,把返回的JSON資料存入一個JSONObject中,然後進行解析
private void retrofitTest(final String userId, final Context context){
Retrofit lRetrofit = new Retrofit.Builder().baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create()).build(); //生成Retrofit物件
final ApiService lApiService = lRetrofit.create(ApiService.class); //生成例項
Call<JSONObject> lHttpResultDtoCall = lApiService.getUserInfo(userId); //請求封裝
lHttpResultDtoCall.enqueue(new Callback<JSONObject>() { //請求結果返回
@Override
public void onResponse(Call<JSONObject> call, Response<JSONObject> response) {
JSONObject result = response.body();
int code = result.getInteger("Code");
//返回Code為0的時候表示有資料返回
if(code == 0){
JSONObject jsonObject = result.getJSONObject("Data");
if(!TextUtils.isEmpty(jsonObject.toString()) && jsonObject.toString() !=null) {
ClassInfoDto lClassInfoDto = JSON.parseObject(jsonObject.toString(),ClassInfoDto.class);
mTextView.setText(lClassInfoDto.getEchoName()); //把返回的資料顯示到的View中
}
}else {
//伺服器端給出的異常資訊
Log.d("retrofit","msg = "+result.getString("Message"));
}
}
@Override
public void onFailure(Call<JSONObject> call, Throwable t) {
//異常處理塊
Log.d("retrofit","e = "+t.toString());
}
});
}
對retrofit的使用方法有一定了解後,來看看如何結合Rxjava與retrofit來訪問網路:此處依然是使用fastJSON解析
1、將RxJava、RxAndroid引入專案中:compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
2、修改ApiService類如下
package com.example.lanzheng.retrofit;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
import rx.Observable;
/**
* Created by lan.zheng on 2016/7/26.
*/
public interface ApiService {
@GET("GetUserInfo")
Call<JSONObject> getUserInfo(@Query("userId") String UserID);
/**
* @param UserID
* @return
*/
@GET("GetUserInfo")
Observable<JSONObject> getUserInfoNew(@Query("userId") String UserID); //RxJava和Retrofit
}
3、Activity類如下:public class RxjavaTestActivity extends AppCompatActivity implements View.OnClickListener,ManagerTest.TestListener
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.tv_rxjava_and_retrofit:
//設定要傳入的資料
String userId = "78a5bcc7-0a97-44db-a430-0b1a1db422f2";
//拿到Retrofit物件並獲得訪問API例項
ApiService lApiService = ManagerTest.getManagerTestInstance().initRetrifit().create(lApiService.class);
//然後獲得網路訪問物件Observable
Observable<JSONObject> lObservable = lApiService .getUserInfoNew(userId);
//真正去網路訪問,獲得結果,結果在下面的回撥中顯示
ManagerTest.getManagerTestInstance().getUserInfoUseRxjava(this,lObservable);
break;
default:
break;
}
}
@Override
public void getUserData(String s) {
Log.d("rxjavafortest","getUserData = "+s); //成功回撥
}
@Override
public void failed(String s) {
Log.d("rxjavafortest","getUserData = "+s); //失敗回撥
}
4.接下來是真正的網路訪問實現環節,這裡我先建立了一個BaseManager基類,這個類有兩個方法,一個用於生成Retrofit物件,一個用於返回網路請求的結果Observable
/**
* Created by lan.zheng on 2016/7/21.
*/
public class BaseManager {
public static Retrofit mRetrofit; //靜態物件
private static final int sTimeout = 40;
private static final String URI = "http://192.168.105.192:7072/TQA/API/MoblieAPI/";
//生成Retrofit物件
private static void getRetrofit() {
if (mRetrofit == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
// Log資訊攔截器
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//設定 Debug Log 模式
builder.addInterceptor(loggingInterceptor);
}
//設定超時時間
builder.connectTimeout(sTimeout, TimeUnit.SECONDS);
builder.readTimeout(sTimeout, TimeUnit.SECONDS);
//錯誤重連
builder.retryOnConnectionFailure(true);
OkHttpClient okHttpClient = builder.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(URI)
//設定 Json 轉換器
.addConverterFactory(GsonConverterFactory.create())
//RxJava 介面卡
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
}
// return mRetrofit;
}
//獲得結果物件返回
public Observable<JSONObject> getDataBack(Observable<JSONObject> lObservable){
Observable<JSONObject> lJSONObjectObservable = Observable.just(lObservable)
.observeOn(Schedulers.io()) //切換到排程器IO去伺服器獲取資料
.flatMap(new Func1<Observable<JSONObject>, Observable<JSONObject>>() {
@Override
public Observable<JSONObject> call(final Observable<JSONObject> httpResultObservable) {
return httpResultObservable.flatMap(new Func1<JSONObject, Observable<JSONObject>>() {
@Override
public Observable<JSONObject> call(final JSONObject httpResult) {
// Observable.error(); //也可以在這裡除了異常
return Observable.create(new Observable.OnSubscribe<JSONObject>(){
@Override
public void call(Subscriber<? super JSONObject> subscriber) {
Log.d("rxjavafortest-result",httpResult.toString()); //獲得JSON資料{"Code":0,"Data":{...},"Message":""}
if(TextUtils.isEmpty(httpResult.toString()) ){
subscriber.onError(new CustomerException("無返回結果"));
return;
}
int code = 0;
String msg = "";
code = httpResult.getInteger("Code");
msg = httpResult.getString("Message");
if(code != 0){
subscriber.onError(new CustomerException(msg));
return;
}
if(TextUtils.isEmpty(httpResult.getString("Data")) || httpResult.getString("Data") == null){
subscriber.onError(new CustomerException("Data為空"));
return;
}
subscriber.onNext(httpResult.getJSONObject("Data"));
subscriber.onCompleted();
}
});
}
});
}
}).unsubscribeOn(Schedulers.io()); //執行結果出來後切換回主執行緒去分發結果
return lJSONObjectObservable;
}
}
5.實現類繼承上面的基類(類名為ManagerTest extendsBaseManager),並宣告一個內部介面用於結果回撥,類的內容如下:
//單例模式,例項化本類
public static class ManagerBuild{ //例項化本類
private static final ManagerTest Instance = new ManagerTest();
}
public static ManagerTest getManagerTestInstance(){
//生成retrofit例項的時候
return ManagerBuild.Instance;
}
public Retrofit initRetrofit(){ //生成Retrofit物件
getRetrofit(); return mRetrofit;
}
private static TestListener testListener;
//用於介面回撥
interface TestListener{
void getUserData(String s);
void failed(String s);
}
//只要是返回型別都是JSON的都可以用這段程式碼拿到最終結果
public void getUserInfoUseRxjava(TestListener t,Observable<JSONObject> lObservable){
testListener = t; //回撥例項
Log.d("rxjavafortest","getUserInfoUseRxjava()");
//結果返回
getDataBack(lObservable).subscribe(new Subscriber<JSONObject>()
{
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
testListener.failed(e.toString());
}
@Override
public void onNext(JSONObject string) {
ClassInfoDto lClassInfoDto = JSON.parseObject(string.toString(),ClassInfoDto.class);
testListener.getUserData(lClassInfoDto.getWorkNo());
}
});
}