封装好的代码,步骤如下(这里是与Rxjava组合使用): 引入库:
//如果仅仅使用HttpURLConnection作为网络层,在app的gralde中添加以下依赖即可:
compile 'com.yolanda.nohttp:nohttp:1.1.0'
//如果要使用OkHttp作为网络层,请再依赖(注意两个lib的版本需要一致):
compile 'com.yanzhenjie.nohttp:okhttp:1.1.0'
// json
compile 'com.alibaba:fastjson:1.1.54.android'
// rx:第三个是为了将订阅与Activity或是fragment生命绑定,在某个特定的是生命周期中解除绑定
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.2.1'
compile 'com.trello:rxlifecycle-components:0.6.1'
一、在Application中对NoHttp进行初始化:
public class NoApplication extends Application {
private static Application _instance;
private static final int CONNENT_TIME_OUT = 30 * 1000;
private static final int READ_TIME_OUT = 30 * 1000;
@Override
public void onCreate() {
super.onCreate();
Logger.setDebug(true); // 开启NoHttp调试模式。
Logger.setTag("NoHttpSample"); // 设置NoHttp打印Log的TAG。
NoHttp.initialize(this, new NoHttp
.Config().setConnectTimeout(CONNENT_TIME_OUT)
.setReadTimeout(READ_TIME_OUT)
.setCacheStore(new DBCacheStore(this).setEnable(true))
.setCookieStore(new DBCookieStore(this).setEnable(true))
.setNetworkExecutor(new OkHttpNetworkExecutor()));
}
public static Application getInstance() {
return _instance;
}
}
二、JavaBeanRequest:
public class JavaBeanRequest<T> extends RestRequest<T> {
// 要解析的JavaBean的class。
private Class<T> clazz;
public JavaBeanRequest(String url, Class<T> clazz) {
this(url, RequestMethod.GET, clazz);
}
public JavaBeanRequest(String url, RequestMethod requestMethod, Class<T> clazz) {
super(url, requestMethod);
this.clazz = clazz;
}
@Override
public T parseResponse(Headers responseHeaders, byte[] responseBody) throws Throwable {
String response = StringRequest.parseResponseString(responseHeaders, responseBody);
// 这里如果数据格式错误,或者解析失败,会在失败的回调方法中返回 ParseError 异常。
return JSON.parseObject(response, clazz);
}
}
三、RxNoHttp:
import android.content.Context;
import android.widget.Toast;
import com.yolanda.nohttp.NoHttp;
import com.yolanda.nohttp.error.NetworkError;
import com.yolanda.nohttp.error.NotFoundCacheError;
import com.yolanda.nohttp.error.ParseError;
import com.yolanda.nohttp.error.TimeoutError;
import com.yolanda.nohttp.error.URLError;
import com.yolanda.nohttp.error.UnKnownHostError;
import com.yolanda.nohttp.rest.IParserRequest;
import com.yolanda.nohttp.rest.Response;
import java.net.ProtocolException;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Created by Yan Zhenjie on 2016/10/16.
*/
public class RxNoHttp {
public static <T> void request(final Context context, final IParserRequest<T> request, final Subscriber subscriber) {
final WaitDialog waitDialog = new WaitDialog(context);
waitDialog.show();
Observable.create(new Observable.OnSubscribe<Response<T>>() {
@Override
public void call(Subscriber<? super Response<T>> subscriber) {
Response<T> response = NoHttp.startRequestSync(request);
if (response.isSucceed()) subscriber.onNext(response);
else subscriber.onError(response.getException());
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Response<T>>() {
@Override
public void onCompleted() {
if (waitDialog.isShowing()){
waitDialog.dismiss();
}
subscriber.onCompleted();
}
@Override
public void onError(Throwable e) {
if (waitDialog.isShowing()){
waitDialog.dismiss();
}
//提示错误信息
if (e instanceof NetworkError){//网络不好
Toast.makeText(context, "请检查你的网络。。。", Toast.LENGTH_SHORT).show();
}else if (e instanceof TimeoutError){//请求超时
Toast.makeText(context,"请求超时,网络不好,或服务器不稳定。。。", Toast.LENGTH_SHORT).show();
}else if (e instanceof UnKnownHostError){//找不到服务器
Toast.makeText(context,"未发现指定服务器,请切换网络后重试。", Toast.LENGTH_SHORT).show();
}else if (e instanceof URLError){//URL是错的
Toast.makeText(context,"URL错误。", Toast.LENGTH_SHORT).show();
}else if (e instanceof NotFoundCacheError){ // 这个异常只会在仅仅查找缓存时没有找到缓存时返回
Toast.makeText(context, "没有找到缓存。", Toast.LENGTH_SHORT).show();
}else if (e instanceof ProtocolException) {
Toast.makeText(context,"系统不支持该请求方法。", Toast.LENGTH_SHORT).show();
} else if (e instanceof ParseError) {
Toast.makeText(context, "解析数据时发生错误。", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "未知错误。", Toast.LENGTH_SHORT).show();
}
subscriber.onError(e);
}
@Override
public void onNext(Response<T> tResponse) {
subscriber.onNext(tResponse);
}
});
}
}
四、观察者:
public abstract class SimpleSubscriber<T> extends Subscriber<T> {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
}
五、等待请求时的progressDialog:
public class WaitDialog extends ProgressDialog {
public WaitDialog(Context context) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setCanceledOnTouchOutside(false);
setProgressStyle(STYLE_SPINNER);
setMessage("请稍等");
}
}
六、根据接口返回的数据创建entity,这里的entity是Weather
七、在Activity中的使用:
Request<Weather> request = new JavaBeanRequest<>("http://v.juhe.cn/weather/index?cityname=%E9%87%91%E5%8D%8E&dtype=json&format=1&key=685992de3183dac1cc42247b58f7ce2d", Weather.class);
RxNoHttp.request(this, request, new SimpleSubscriber<Response<Weather>>() {
@Override
public void onNext(Response<Weather> weatherResponse) {
Weather data = weatherResponse.get();
mAdapter = new FutureListAdapter(MainActivity.this,getFuture(data.getResult().getFuture()));
list.setAdapter(mAdapter);
// result.setText( "today:" + data.getResult().getToday().getCity());
Log.d("MainActivity", "sk:" + data.getResult().getSk().getHumidity());
Log.d("MainActivity", "future:" + data.getResult().getFuture().getDay_20161129().getDate());
}
});
提示: 如果提示“未知错误”可能是我们在next中出现空指针之类的错误,我们只需将第三步中的错误打印出来即可。