1.AndroidStudio 添加依赖
implementation 'io.reactivex:rxjava:1.3.2'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
2.常量类 设置超时时间
public class ROConstants {
public static final long timeout=20;//超时时间20秒
}
3.工具类 获取 OkHttpClient 对象 封装get post以及下载图片方法
package com.wjn.rxandroidokhttpdemo.utils;
import com.wjn.rxandroidokhttpdemo.constants.ROConstants;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
public class RxAndroidOkhttp {
private OkHttpClient mOkHttpClient = null;//OkHttpClient 对象
private static RxAndroidOkhttp mRxAndroidOkhttp = null;//RxAndroidOkhttp 对象
/**
* 构造方法私有化
*/
private RxAndroidOkhttp() {
//创建okhttp对象 以及连接,读,取超时时间
mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//连接时间
.readTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//读时间
.writeTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//写时间
.retryOnConnectionFailure(true)//连接失败后是否重新连接
.build();
}
/**
* 获取此单例类对象的方法
*/
public static RxAndroidOkhttp getInstance() {
if (null == mRxAndroidOkhttp) {//单例对象为空
synchronized (RxAndroidOkhttp.class) {
mRxAndroidOkhttp = new RxAndroidOkhttp();
}
}
return mRxAndroidOkhttp;
}
/**
* get方法
* */
public Observable<String> get(final String url) {
//创建被观察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
final Subscriber mSubscriber = subscriber;
//没有取消订阅的时候
if (!mSubscriber.isUnsubscribed()) {
//get请求
Request request = new Request.Builder().url(url).get().build();
if (null != mOkHttpClient) {
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//通知订阅者的错误信息
mSubscriber.onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (null != response && response.isSuccessful()) {
//通知订阅者的成功信息
mSubscriber.onNext(response.body().string());
}
//通知完毕
mSubscriber.onCompleted();
}
});
}
}
}
});
return observable;
}
/**
* Post方法
* */
public Observable<String> post(final String url, final Map<String, String> params) {
//创建被观察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
final Subscriber mSubscriber = subscriber;
//没有取消订阅的时候
if (!mSubscriber.isUnsubscribed()) {
//获取FormBody.Builder 对象
FormBody.Builder builder = new FormBody.Builder();
//遍历params 将其放入到FormBody.Builder 对象
if (params != null && !params.isEmpty()) {
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.add(entry.getKey(), entry.getValue());
}
}
//获取RequestBody 对象
RequestBody requestBody = builder.build();
//构建post请求
Request request = new Request.Builder().url(url).post(requestBody).build();
if (mOkHttpClient != null) {
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//通知订阅者的错误信息
mSubscriber.onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (null != response && response.isSuccessful()) {
//通知订阅者的成功信息
mSubscriber.onNext(response.body().string());
}
//通知完毕
mSubscriber.onCompleted();
}
});
}
}
}
});
return observable;
}
/**
* 下载图片
* */
public Observable<byte[]> loadImageViewByUrl(final String url) {
//创建被观察者
Observable<byte[]> observable = Observable.create(new Observable.OnSubscribe<byte[]>() {
@Override
public void call(Subscriber<? super byte[]> subscriber) {
final Subscriber mSubscriber = subscriber;
//没有取消订阅的时候
if (!mSubscriber.isUnsubscribed()) {
//网络请求请求
Request request = new Request.Builder().url(url).get().build();
if (null != mOkHttpClient) {
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//通知订阅者的错误信息
mSubscriber.onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (null != response && response.isSuccessful()) {
//通知订阅者的成功信息
byte[] data = response.body().bytes();
if (data != null) {
mSubscriber.onNext(data);
}
}
//通知完毕
mSubscriber.onCompleted();
}
});
}
}
}
});
return observable;
}
}
4.实现activity
package com.wjn.rxandroidokhttpdemo.activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.wjn.rxandroidokhttpdemo.R;
import com.wjn.rxandroidokhttpdemo.utils.RxAndroidOkhttp;
import java.util.HashMap;
import java.util.Map;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private TextView gettextview;
private TextView posttextview;
private TextView loadimageviewtextview;
private ImageView imageview;
private TextView resulttextview;
private RxAndroidOkhttp mRxAndroidOkhttp=null;//RxAndroidOkhttp对象
private Observable<String> mObservable=null;//get post 方式请求的Observable对象
private Observable<byte[]> mimgObservable=null;//下载图片的Observable
private String geturl="http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue";//get方式的请求路径
private String posturl="http://fanyi.youdao.com/openapi.do";//post方式的请求路径
private String imageviewurl="http://upload.site.cnhubei.com/2016/0117/1453000952567.jpg";//下载图片的路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
/**
* 初始化各种View的方法
* */
private void initView(){
gettextview= (TextView) findViewById(R.id.activity_main_gettextview);
posttextview= (TextView) findViewById(R.id.activity_main_posttextview);
loadimageviewtextview= (TextView) findViewById(R.id.activity_main_loadimageviewtextview);
imageview= (ImageView) findViewById(R.id.activity_main_loadimageviewimageview);
resulttextview= (TextView) findViewById(R.id.activity_mainresulttextview);
gettextview.setOnClickListener(this);
posttextview.setOnClickListener(this);
loadimageviewtextview.setOnClickListener(this);
mRxAndroidOkhttp=RxAndroidOkhttp.getInstance();
}
/**
* 各种点击事件的方法
* */
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.activity_main_gettextview://get方式获取数据
if(null!=mRxAndroidOkhttp){
resulttextview.setText("数据加载中...");
//observable定义被观察者
mObservable=mRxAndroidOkhttp.get(geturl);
if(null!=mObservable){
//定义观察者
Subscriber<String> mSubscriber=new Subscriber<String>(){
@Override
public void onCompleted() {
Log.d("MainActivity","get----onCompleted方法!!!");
}
@Override
public void onError(Throwable e) {
resulttextview.setText(e.getMessage());
Log.d("MainActivity","get----onError方法!!!e.toString()----:"+e.toString());
}
@Override
public void onNext(String s) {
Log.d("MainActivity","get----onNext方法!!!s----:"+s);
resulttextview.setText("get方式请求结果:\n"+s);
}
};
/**
* 订阅者关联被观察者
* Schedulers.io()说明是输入输出的计划任务
* AndroidSchedulers.mainThread()说明订阅者是中ui主线程中执行
* */
mObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mSubscriber);
}
}
break;
case R.id.activity_main_posttextview://post方式获取数据
if(null!=mRxAndroidOkhttp){
Map<String, String> params = new HashMap<>();
params.put("keyfrom", "imoocdict123456");
params.put("key", "324273592");
params.put("type", "data");
params.put("doctype", "json");
params.put("version", "1.1");
params.put("q", "red");
resulttextview.setText("数据加载中...");
//observable定义被观察者
mObservable=mRxAndroidOkhttp.post(posturl,params);
if(null!=mObservable){
//定义观察者
Subscriber<String> mSubscriber=new Subscriber<String>(){
@Override
public void onCompleted() {
Log.d("MainActivity","post----onCompleted方法!!!");
}
@Override
public void onError(Throwable e) {
resulttextview.setText(e.getMessage());
Log.d("MainActivity","post----onError方法!!!e.toString()----:"+e.toString());
}
@Override
public void onNext(String s) {
Log.d("MainActivity","post----onNext方法!!!s----:"+s);
resulttextview.setText("post方式请求结果:\n"+s);
}
};
/**
* 订阅者关联被观察者
* Schedulers.io()说明是输入输出的计划任务
* AndroidSchedulers.mainThread()说明订阅者是中ui主线程中执行
* */
mObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mSubscriber);
}
}
break;
case R.id.activity_main_loadimageviewtextview://下载图片
if(null!=mRxAndroidOkhttp){
loadimageviewtextview.setText("下载中...");
//observable定义被观察者
mimgObservable=mRxAndroidOkhttp.loadImageViewByUrl(imageviewurl);
//定义观察者
Subscriber<byte[]> mSubscriber=new Subscriber<byte[]>(){
@Override
public void onCompleted() {
Log.d("MainActivity","loadimagview----onCompleted方法!!!");
}
@Override
public void onError(Throwable e) {
loadimageviewtextview.setText(e.getMessage());
Log.d("MainActivity","loadimageview----onError方法!!!e.toString()----:"+e.toString());
}
@Override
public void onNext(byte[] bytes) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if((null!=bitmap)&&(!bitmap.isRecycled())){
imageview.setImageBitmap(bitmap);
}
loadimageviewtextview.setText("下载图片");
}
};
/**
* 订阅者关联被观察者
* Schedulers.io()说明是输入输出的计划任务
* AndroidSchedulers.mainThread()说明订阅者是中ui主线程中执行
* */
mimgObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mSubscriber);
}
break;
}
}
}
5.补充:OKHTTP请求成功之后在onResponse方法中可以得到一个Response对象。
1.如果想获得返回的字符串结果则可以通过response.body().string()。
2.如果想获得返回结果的二进制数据的话可以通过response.body().bytes()。
3.如果想获得返回的InputStream的话可以通过response.body().byteStream()。
6.OkHttp的主角们
1.OkHttpClient
Factory for calls, which can be used to send HTTP requests and read their responses.
工厂生产者,负责生产calls。
OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//连接时间
.readTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//读时间
.writeTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//写时间
.build();
2.Request
OkHttp的请求,通过Request.Builder().build
创建, Request.Builder()
配置请求信息,如请求方式get/post
等、请求参数RequestBody
、请求头header
。
Request request = new Request.Builder().addHeader("cookie", cookie).url(url).get().build();
3.Call
调度者,Call作顶级接口,具体实现由RealCall负责。负责Request
和Response
的桥梁作用,将Request
以execute()
同步的方式执行输出Response
, 或将Request
以enqueue(callback)
异步的方式加入调度。
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
7.OKHttp框架GitHub链接:https://github.com/square/okhttp