Rxjava+retrofit共通要求パラメータおよび要求結果パッケージの追加
20748 ワード
RxJava+Retrofit+okHttpは現在androidの主流のネットワーク要求フレームワークとして、自分のプロジェクトでの応用を書きます!本文の主な内容:1.使用するリクエストに共通のリクエストパラメータを追加します.2.自分のプロジェクトに適したサーバインタフェースデータ処理クラスをカプセル化する.
開発環境
retrofitVersion=‘2.2.0’ok 3 Version=‘3.6.0’rxjavaVersion=‘1.2.7’rxAndroid Version=‘1.2.1’rxlifecycleVersion=‘0.3.0’rxlifecycleVersionは、RxJavaにおけるsubscriptionによるメモリリークを防止するために誕生した.たとえば、参照するview(fragment,activity)が破棄されますが、rxjavaライフサイクルが終了していない場合、破棄されたview(fragment,activity)を再度呼び出すと異常が発生します.はPostインタフェースのように形成されています.http://base/interface/xxx各インタフェースには、APPTOKEN(登録ユーザ登録状態)の戻り値が である必要がある.
まず、すべてのリクエストにデフォルトのapptokenフィールドを追加します.Okhttp 3のネットワークブロッカーInterceptorを使用します.コアコード:
上記の2つのネットワークブロッカーが追加され、apptokenを追加するブロッカーはアプリケーションブロッカー(Application Intercetor)、ネットワーク異常を追加するブロッカーはネットワークブロッカー(netErrorInterceptor)である.
ネットワーク異常を追加するブロッキングの主な役割は、後続の結果セットをカプセル化する際にネットワーク異常を追加する必要がない場合です.
apptokenパラメータ追加ブロッキングの詳細な実装:
requestリクエストをブロックしてapptokenのpostフィールドを追加します.*次に3つの戻りタイプを解析し,一般的にappインタフェースはこの3つの場合に差が少ないはずである.1.第1種について:
{"erron":"100000","msg":"成功"}//インタフェースは単純メッセージ情報を返す
カスタム処理結果BaseBeanSubscribe
このコードセグメントは、結果フィルタセットに基づいてエラーを処理する場合を実現する.ネットワーク異常は、上述したように処理されているため、ここでは直接ネットワーク異常を取得することができる.
2 . 2つ目:
{"data":{},"erron":"100000","msg":"成功"}//インタフェースは詳細フィールドを返します
このように書くメリットは、onSuccessで返されるデータが「data」{}のデータであることです.3.最後のタイプ、ページング:
{「nowPage」:“1”,“totalPage”:“4”,“data”:[],“erron”:“100000”,“msg”:“成功”}
onSucessでリストセットを返し、totalpage、nowpage*が最後に上記の準備を完了すると、コードの使用は簡単になりますeg:インタフェースがあります
@POST(“admin/index/surnames”) @FormUrlEncoded Observable getBjxList(@Field(“id”) String id);
開発環境
retrofitVersion=‘2.2.0’ok 3 Version=‘3.6.0’rxjavaVersion=‘1.2.7’rxAndroid Version=‘1.2.1’rxlifecycleVersion=‘0.3.0’rxlifecycleVersionは、RxJavaにおけるsubscriptionによるメモリリークを防止するために誕生した.たとえば、参照するview(fragment,activity)が破棄されますが、rxjavaライフサイクルが終了していない場合、破棄されたview(fragment,activity)を再度呼び出すと異常が発生します.
{"erron":"100000","msg":" "}//
{"data":{},"erron":"100000","msg":" "}//
{"nowPage":"1","totalPage":"4","data":[],"erron":"100000","msg":" "}//
まず、すべてのリクエストにデフォルトのapptokenフィールドを追加します.Okhttp 3のネットワークブロッカーInterceptorを使用します.コアコード:
builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(logging);
}
builder.connectTimeout(6 * 1000, TimeUnit.MILLISECONDS)//10s
.readTimeout(10 * 1000, TimeUnit.MILLISECONDS)
.writeTimeout(10 * 1000, TimeUnit.MILLISECONDS);
// token
builder.addInterceptor(new TokenInterceptord());
//
Interceptor netErrorInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
if (NetWorkUtil.isNetworkConnected())
return chain.proceed(chain.request());
else {
String res = "{\"erron\":\"-1200\",\"msg\":\" \",\"nowPage\":\"0\",\"totalPage\":\"0\"}";
Response response = new Response.Builder()
.code(200)
.request(chain.request())
.protocol(Protocol.HTTP_1_1)
.addHeader("Cache-Control", "no-cache")
.addHeader("Content-Type", "text/html; charset=utf-8")
.body(RealResponseBody.create(MediaType.parse("text"), res.getBytes("utf-8")))
.build();
return response;
}
}
};
builder.addNetworkInterceptor(netErrorInterceptor);
上記の2つのネットワークブロッカーが追加され、apptokenを追加するブロッカーはアプリケーションブロッカー(Application Intercetor)、ネットワーク異常を追加するブロッカーはネットワークブロッカー(netErrorInterceptor)である.
ネットワーク異常を追加するブロッキングの主な役割は、後続の結果セットをカプセル化する際にネットワーク異常を追加する必要がない場合です.
apptokenパラメータ追加ブロッキングの詳細な実装:
public class TokenInterceptord implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
if (canInjectIntoBody(request)) {
FormBody.Builder formBodyBuilder = new FormBody.Builder();
formBodyBuilder.add("apptoken", SharedPreUtil.getAppToken());// apptoken
RequestBody formBody = formBodyBuilder.build();
String postBodyString = bodyToString(request.body());
postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
}
request=requestBuilder.build();
return chain.proceed(request);
}
private boolean canInjectIntoBody(Request request) {
if (request == null) {
return false;
}
if (!TextUtils.equals(request.method(), "POST")) {
return false;
}
RequestBody body = request.body();
if (body == null) {
return false;
}
MediaType mediaType = body.contentType();
if (mediaType == null) {
return false;
}
if (!TextUtils.equals(mediaType.subtype(), "x-www-form-urlencoded")) {
return false;
}
return true;
}
private String bodyToString(final RequestBody request) {
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if (copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}
}
requestリクエストをブロックしてapptokenのpostフィールドを追加します.*次に3つの戻りタイプを解析し,一般的にappインタフェースはこの3つの場合に差が少ないはずである.1.第1種について:
{"erron":"100000","msg":"成功"}//インタフェースは単純メッセージ情報を返す
カスタム処理結果BaseBeanSubscribe
public abstract class BaseBeanSubscribe<T extends BaseBean> extends Subscriber<T> {
public enum ERROR_TYPE {
DATA_EMPTY,//
DATA_ERROR,//
NET_ERROR,//
TOKEEN_ERROR,//apptoken 。
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
LogUtils.i("Zuzu", "ResultSubscriber-->exception");
e.printStackTrace();
if (NetWorkUtil.isNetworkConnected()) {
onError(ERROR_TYPE.DATA_ERROR, " !");
} else {
onError(ERROR_TYPE.NET_ERROR, " , !");
}
LogUtils.i("Zuzu", "request fail!");
}
@Override
public void onNext(T t) {
if (t == null) {
LogUtils.i("Zuzu", "data_empty!");
onError(ERROR_TYPE.DATA_EMPTY, " !");
} else if ("100002".equals(t.getErron()) || "100003".equals(t.getErron())) {
String msg;
if ("-1".equals(SharedPreUtil.getAppToken())) {
msg = " , !";
} else {
msg = " , !";
}
onError(ERROR_TYPE.TOKEEN_ERROR, msg);
} else if ("100000".equals(t.getErron())) {
sucess();
} else if ("-1200".equals(t.getErron())) {
onError(ERROR_TYPE.NET_ERROR, t.getMsg());
} else {
onError(ERROR_TYPE.DATA_ERROR, t.getMsg());
}
}
//
protected abstract void sucess();
// !
protected abstract void onError(ERROR_TYPE type, String msg);
}
basebean
public class BaseBean<T> {
private String erron;
private String msg;
private T data;
...set get ...
}
このコードセグメントは、結果フィルタセットに基づいてエラーを処理する場合を実現する.ネットワーク異常は、上述したように処理されているため、ここでは直接ネットワーク異常を取得することができる.
2 . 2つ目:
{"data":{},"erron":"100000","msg":"成功"}//インタフェースは詳細フィールドを返します
public abstract class ResultSubscriber<D, T extends BaseBean<D>> extends BaseBeanSubscribe<T> {
@Override
public void onNext(T t) {
if (t != null && "100000".equals(t.getErron())) {
onSuccess(t.getData());
return;
}
super.onNext(t);
}
@Override
protected void sucess() {
}
//
protected abstract void onSuccess(D data);
}
このように書くメリットは、onSuccessで返されるデータが「data」{}のデータであることです.3.最後のタイプ、ページング:
{「nowPage」:“1”,“totalPage”:“4”,“data”:[],“erron”:“100000”,“msg”:“成功”}
public abstract class PageListResultSubscriber<D, T extends BasePageBean<D>> extends ResultSubscriber<List<D>, T> {
@Override
public void onNext(T t) {
if (t != null && "100000".equals(t.getErron())) {
onSuccess(t.getData(), Integer.parseInt(t.getNowPage()), Integer.parseInt(t.getTotalPage()));
return;
}
super.onNext(t);
}
protected abstract void onSuccess(List data, int nowPage, int totalPage);
@Override
protected void onSuccess(List data) {
//
}
onSucessでリストセットを返し、totalpage、nowpage*が最後に上記の準備を完了すると、コードの使用は簡単になりますeg:インタフェースがあります
@POST(“admin/index/surnames”) @FormUrlEncoded Observable getBjxList(@Field(“id”) String id);
mService.getBjxList("0")
.compose(getView().bindToLifecycle())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ResultSubscriber,BjxListBean>() {
@Override
protected void onSuccess(List data) {
if(getView()!=null)
{
getView().showSucessUi(data);
}
}
@Override
protected void onError(ERROR_TYPE type, String msg) {
if(getView()!=null)
{
getView().showError(type,msg);
}
}
});
BjxListBean
public class BjxListBean extends BaseBean<List<BjxListBean.DataBean>> {
public static class DataBean implements Serializable{
private String id;
private String xing;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getXing() {
return xing;
}
public void setXing(String xing) {
this.xing = xing;
}
}
}