[置顶] OKhttp、RXjava与retrofit的网络访问使用

时间:2021-11-28 05:28:55
两个月没有写微博了,无论如何,现在再次回归Android的打怪升级。

关于Rxjava的学习和介绍,有兴趣的可以去云盘中提取pdf资料,这里不做详解,地址和提取码如下:链接:http://pan.baidu.com/s/1skDOjN3 密码: ajv7。

要想Rxjava和Retrofit结合使用,我们先简单了解一下什么是Retrofit:Square提供的开源产品,为Android平台的应用提供一个类型安全的REST客户端。


只使用Retrofit来访问网络: 1.准备:此处模拟网络返回的数据格式为JSON,这里使用fastjson来做为解析工具(Android自带的JSON解析工具功能没有那么强大,有可能会引发问题,不推荐使用),引入此jar包,要使用Retrofit需在gradle引入依赖:compile 'com.squareup.retrofit2:retrofit:2.0.2'
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'  


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());
}
});
}

[置顶]        OKhttp、RXjava与retrofit的网络访问使用