[置顶] Retrofit+Rxjava的封装

时间:2023-01-20 17:44:32

概念:

RxJava

用途:【异步】:asynctask / new thread。
优点:【简洁】:程序逻辑为链式结构,没有嵌套。
实现方式:【观察者模式】。
基本概念:
Observable (可观察者,即被观察者)、
Observer (Subscriber、观察者)、
subscribe (订阅)、
事件。

Retrofit

Square提供的开源产品,是一个 RESTful 的 HTTP 网络请求框架的封装
Retrofit 利用【方法上的注解】将【接口】转化成一个【 HTTP 请求】。

优点:让代码结构更加清晰,它可以直接解析JSON数据变成JAVA对象,支持回调操作,处理不同的结果。

实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作,在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit。

OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势,其核心主要有路由、连接协议、拦截器、代理、安全性认证、连接池以及网络适配,拦截器主要是指添加,移除或者转换请求或者回应的头部信息

依赖

/* retrofit系列:请求*/
compile 'com.squareup.retrofit2:retrofit:2.1.0'

//使用gson解析json
compile 'com.google.code.gson:gson:2.7'

//retrofit支持gson
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

//使用Jackson解析json
compile 'org.codehaus.jackson:jackson-asl:0.9.5'

//retrofit支持Jackson
compile 'com.squareup.retrofit2:converter-jackson:2.1.0'

//添加retrofit支持rxjava异步
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

/* rx系列:异步*/
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.10'

权限:

<uses-permission android:name="android.permission.INTERNET"/>
  • 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".activity.MainActivity">


<Button
android:id="@+id/btn_rx"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="btn"
android:text="rx+retrofit绝对封装"/>



<TextView
android:id="@+id/tv_msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</LinearLayout>
  • 代码结构

[置顶]        Retrofit+Rxjava的封装

基本使用

 private void unWrapperRetrofit() {
//提示对话框
final ProgressDialog pDialog = new ProgressDialog(MainActivity.this);
pDialog.setIcon(R.mipmap.ic_launcher);
pDialog.setMessage("正在加载中...");
pDialog.setTitle("提示");

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor() // .setLevel(HttpLoggingInterceptor.Level.BODY);

//创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) //
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) //设置读取超时
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) //设置读取超时
.addInterceptor(interceptor) //添加日志拦截器(该方法也可以设置公共参数,头信息)
//开启响应缓存(数据不能实时) //getCacheDir()方法用于获取/data/data//cache目录
//getFilesDir()方法用于获取/data/data//files目录 //
.cache(newCache(new File(context.getCacheDir(), "HttpResponseCache"), CHCHE_SIZE))
.build();

//创建retrofit
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)//使用OKHttpClient网络请求
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(JacksonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(Config.BASE_URL)
.build();

//请求数据、解析回调、更新UI
retrofit.create(HttpService.class) //创建service
.getAllVedioBy(true) //请求数据
.subscribeOn(Schedulers.io()) //rx.schedulers.Schedulers
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Model>() {
@Override
public void onCompleted() { //请求完成取消对话框
if (pDialog.isShowing() && pDialog != null) {
pDialog.dismiss();
}
}

@Override
public void onError(Throwable e) { //请求错误取消对话框
if (pDialog.isShowing() && pDialog != null) {
pDialog.dismiss();
}
}

@Override
public void onStart() { //请求开始显示对话框
super.onStart();
pDialog.show();
}

@Override
public void onNext(Model model) { //参数为请求的结果
tv1.setText("无封装:\n" + model.getData().toString());
}
});
}

封装使用

1、调用

private void MyWrapperRetrofitWY() {
HttpManager httpManager = HttpManager.getInstance(MainActivity.this);
HttpService httpService = httpManager.getHttpService(Config.BASE_URL_WY);
httpManager.doHttpGet(httpService.getWYDataBy(),
new ProgressSubscriber(new ProgressSubscriber
.HttpOnNextListener<WYModel>() {
@Override
public void onNext(WYModel model) {
tv4.setText("我我我我我的封装:\n" + model
.getT1348647909107().toString());
}
}, MainActivity.this, true));
}

2、自定义Subscriber

public class ProgressSubscriber<T> extends Subscriber<T> {

private ProgressDialog pd;
private Context mContext;
private boolean cancel;// 是否能取消请求
private HttpOnNextListener mSubscriberOnNextListener; // 回调接口

public ProgressSubscriber(HttpOnNextListener subscriberOnNextListener, Context context) {
mSubscriberOnNextListener = subscriberOnNextListener;
mContext = context;
initProgressDialog(context);
}

public ProgressSubscriber(HttpOnNextListener subscriberOnNextListener, Context context, boolean cancel) {
mSubscriberOnNextListener = subscriberOnNextListener;
mContext = context;
this.cancel = cancel;
initProgressDialog(context);
}

@Override
public void onStart() {
super.onStart();
showProgressDialog();
}

@Override
public void onCompleted() {
dismissProgressDialog();
}

@Override
public void onError(Throwable e) {
if (e instanceof SocketTimeoutException) {
Toast.makeText(mContext, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();
} else if (e instanceof ConnectException) {
Toast.makeText(mContext, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, "错误" + e.getMessage(), Toast.LENGTH_SHORT).show();
Log.i("tag", "error----------->" + e.toString());
}
dismissProgressDialog();
}

/**
* 将onNext方法中的返回结果交给Activity或Fragment自己处理
*
* @param t 创建Subscriber时的泛型类型
*/

@Override
public void onNext(T t) {
if (mSubscriberOnNextListener != null) {
mSubscriberOnNextListener.onNext(t);
}
}

/**
* 初始化进度框
*/

private void initProgressDialog(Context context) {
pd = new ProgressDialog(context); // pd.setIcon(R.mipmap.ic_launcher); // pd.setMessage("正在加载中..."); // pd.setTitle("提示");

pd.setCancelable(cancel);
if (cancel) {
pd.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
//取消ProgressDialog的时候,取消对observable的订阅,同时也取消了http请求
if (!isUnsubscribed()) {//订阅了则取消
unsubscribe();
}
}
});
}
}

/**
* 显示进度框
*/

public void showProgressDialog() {
if (pd == null || mContext == null) {
return;
}
if (!pd.isShowing()) {
pd.show();
}
}

/**
* 取消进度框
*/

public void dismissProgressDialog() {
if (pd != null && pd.isShowing()) {
pd.dismiss();
}
}

/**
* 成功回调接口
*/

public interface HttpOnNextListener<T> {
void onNext(T t);
}/**/


}

3、接口配置,完整接口URL为:
http://c.m.163.com/nc/article/headline/T1348647909107/0-20.html

 public static final String BASE_URL_WY = "http://c.m.163.com/";
public interface HttpService {
@GET("nc/article/headline/T1348647909107/0-20.html")
Observable<WYModel> getWYDataBy (); }

4、http处理封装类

public class HttpManager {

private static final int DEFAULT_TIMEOUT = 6;
private volatile static HttpManager httpManager;//volatile用来修饰被不同线程访问和修改的变量
private HttpService httpService;
private Context context;
private String url;

public HttpManager() {
}

//构造方法私有
private HttpManager(Context context) {
this.context = context;
}

public HttpService getHttpService(String url) {
//创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.build();

//创建retrofit
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(url) //URL会不同
.build();
return retrofit.create(HttpService.class);
}

//获取单例方法公开
public static HttpManager getInstance(Context context) {
if (httpManager == null) {
synchronized (HttpManager.class) {
if (httpManager == null) {
httpManager = new HttpManager(context);
}
}
}
return httpManager;
}

/**
* 封装
*/

public void doHttp(Observable observable, Subscriber subscriber) {
//请求数据、解析回调、更新UI
observable.subscribeOn(Schedulers.io()) //rx.schedulers.Schedulers
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}

}

5、实体类WYModel(GsonFormat自动生成即可,这里直接略)