概念:
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>
- 代码结构
基本使用
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自动生成即可,这里直接略)