Retrofit2+RxJava封裝的網路框架(上)
在2016年7月份,有幸封裝了Retrofit2+RxJava+Builder設計模式的網路框架。在今年去面試的過程中,被面試官提及Retrofit2和RxJava的知識,我竟有些答不出來,這令我非常難過。看來就算自己做過的東西也難免會忘的一乾二淨,這裡呢,我將重新封裝一下這個網路框架,並整理成部落格,供大家相互學習,並加深一下自己的印象,避免不必要的尷尬。
我計劃在今年(2018)年底將我的快速開發框架上傳Github,到時候我會在這篇博文中貼出地址,望大家到時候支援一下喲。可能有人會問這麼一個問題:都有那麼多輪子了,你為什麼還要造輪子呢?針對於這個問題我會針對於兩個方向進行回答。
1.針對於公司,當然是用現成的輪子,因為專案當然是越快結項越好呀,自己造輪子耗時耗力。 2.針對於你自己,如果你想成長,就必須有造輪子的能力,這個快速開發框架是我閒的時候,工作之餘搭建的,耗時兩個月,期間既痛苦又快樂。 當完成的那一刻,向同事推薦出去,收到了讚賞和意見。都要虛心接受喲。這個封裝好的網路框架就是其中之一。
廢話不多說,大家現在看一下我封裝的目錄結構
解析:
1.bean目錄 -- 用來參與解析的實體類 2.cookie目錄 -- 主要用來持久化cookie的 3.gsonutil目錄 -- GSON解析的封裝,本來打算用大<T>解析的, 但是我一直未找到讓GSON支援大<T>的解決辦法,GSON只能處於解析實體類的地步。 所以就用了String解析。 4.loggingInterceptors目錄 -- Log的封裝,這是從網上下載的,是對HttpLoggingInterceptor的再次封裝,友好的列印網路日誌,序列化後縮排分明,展示清晰。 5.BaseRetrofitConfig -- 配置檔案,包括baseUrl、追加公共引數等資訊 6.BaseRetrofitFactory -- (1).配置OkHttpClient、新增攔截器 (2).新增HttpLoggingInterceptorM 日誌攔截 (3).配置Retrofit 7.BaseRetrofitTwoService -- 網路請求介面Retrofit 2.+ 8.NetModle -- 實現get post等方法,可在外部直接使用,極其方便。 9.NetSubscriber -- 可以在本類中對 Subscriber 獲取到的資料進行處理。 10.OnNetSubscriberListener -- 自定義網路資料回撥介面 11.tool目錄 -- 工具類,包含LogUtil 12.Switch -- 有個方法控制是否列印Log,正式釋出後關閉這個功能,其他功能不在介紹。
正文開始
第一步:建立快速開發框架(Moudle方式)
Moudle方式的好處是可隨便移植,靈活性高,高效便捷。如果不懂的話請看我整理的另一篇博文,專門講解Moudle的用法。《Android中Moudle的詳細使用教程》
第二步:修改剛建立好的Moudle中的build.gradle檔案
在
/* - 返回型別支援String - */
compile 'com.squareup.retrofit2:converter-scalars:2.0.0'//retrofit 框架 優化新增 +001
之上的程式碼,都是網路框架所用到的,包括這個,後面都有備註。我加的其他控制元件是快速開發框架裡別的東西,你們做網路框架,只需要新增8個retrofit的依賴就行了,看備註後面有1/8r、2/8r的那8個
dependencies { compile 'com.android.support:appcompat-v7:25.3.1' compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' /* - (可選)okhttp3日誌攔截器 除錯使用,專案中存在自己封裝的!!!,本包可不用 - */ // compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'//okhttp log攔截 版本必須和okhttp一致 1/8r /* - okhttp3 - */ compile 'com.squareup.okhttp3:okhttp:3.4.1'//picasso + okHttp 2/2p retrofit 框架 2/8r /* - retrofit2 - */ compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit 框架 3/8r /* - gson - */ compile 'com.google.code.gson:gson:2.7'//retrofit 框架 4/8r /* - retrofit2使用gson需要新增這個包 - */ compile 'com.squareup.retrofit2:converter-gson:2.1.0'//retrofit 框架 5/8r /* - retrofit2使用rxjava需要新增這個包 - */ compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'//retrofit 框架 6/8r /* - 執行緒問題使用rxjava需要使用這個包 - */ compile 'io.reactivex:rxandroid:1.1.0'//retrofit 框架 7/8r /* - rxjava - */ compile 'io.reactivex:rxjava:1.1.0'//retrofit 框架 8/8r /* - 返回型別支援String - */ compile 'com.squareup.retrofit2:converter-scalars:2.0.0'//retrofit 框架 優化新增 +001 /* - 圖片選擇器 - */ // compile 'com.lzy.widget:imagepicker:0.3.2' //指定版本 compile 'com.lzy.widget:imagepicker:0.5.5' //指定版本 compile 'com.github.nanchen2251:CompressHelper:1.0.5' //壓縮配套使用 /* - picasso - */ compile 'com.squareup.picasso:picasso:2.5.2'//picasso + okHttp 1/2p /* - butterknife - */ //臨時沒有有效方法可以讓本控制元件支援library // compile 'com.jakewharton:butterknife:8.4.0' //butterknife // // apt 'com.jakewharton:butterknife-compiler:8.4.0' //butterknife /* - 基於frame的新型下拉重新整理控制元件 - */ compile 'com.lcodecorex:tkrefreshlayout:1.0.5' //掃碼思密達 compile 'com.google.zxing:core:3.2.1' //掃碼所需包 compile 'pub.devrel:easypermissions:0.1.7' //許可權 compile 'cn.bingoogolapple:bga-qrcodecore:[email protected]' //掃碼所需包 compile 'cn.bingoogolapple:bga-zxing:[email protected]' }
第三步:開始寫程式碼
這篇文件我是分了上下兩篇分開寫的,上篇主要是講的是重點程式碼,下篇講的是輔助程式碼和用法。
重點程式碼只有這六個
5.BaseRetrofitConfig -- 配置檔案,包括baseUrl、追加公共引數等資訊
6.BaseRetrofitFactory -- (1).配置OkHttpClient、新增攔截器
(2).新增HttpLoggingInterceptorM 日誌攔截 (3).配置Retrofit
7.BaseRetrofitTwoService -- 網路請求介面Retrofit 2.+
8.NetModle -- 實現get post等方法,可在外部直接使用,極其方便。
9.NetSubscriber -- 可以在本類中對 Subscriber 獲取到的資料進行處理。
10.OnNetSubscriberListener -- 自定義網路資料回撥介面
我將按順序貼出程式碼,並講解
這個是配置檔案類,主要功能是設定引數,初始地址和超時時間等。初始化http的header響應頭方便進行驗籤。
package com.abysskitty.frame.network;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.ArrayMap;
import android.util.Log;
import com.abysskitty.frame.base.BaseApplication;
import com.abysskitty.frame.tool.DateUtil;
import com.abysskitty.frame.tool.EncryptUtil;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Created by AbyssKitty on 2016/10/9.
* Version 1.0
* 配置檔案,包括baseUrl、追加公共引數等資訊
*/
public class BaseRetrofitConfig {
/**
* 總url路徑 - 注意:Retrofit2.0 的baseUrl必須以“ / ”結尾,不然會丟擲IllegalArgumentException異常
* Retrofit2.0 支援全URL路徑輸入 所以在這裡的路徑就是個擺設,但卻不能缺少
* */
public static final String baseUrl = "http://127.0.0.1:8080/api/v1/";
/**
* 連線超時時間,預設15s
* */
public static final int OKHTTP_OVERTIME = 15;
/**
* 需要追加的公共引數
* Parame -> 未訪問伺服器之前,把此map拼接到上傳的引數中
* hander -> 開始訪問伺服器之前,把此map新增到hander響應頭
* */
private static Map<String,String> Parame = new HashMap<>();
private static Map<String,String> header = new HashMap<>();
/**
* 對 NetModle 開放獲取公共引數的方法,此引數直接追加在parame中
* 過時方法,已摒棄,需要在程式中動態新增
* */
@Deprecated
public static Map getCommonParameter(){
Parame.clear();
Parame = new HashMap<>();
//Parame.put("","");
return Parame;
}
/**
* 對 NetModle 開放獲取公共引數方法,此方法追加在headers裡
* 過時方法,已摒棄,根據專案需求,-必須或者需要-在程式中動態新增
* */
@Deprecated
public static Map getHanderCommonParameter() {
header.clear();
// header = getHeasers();
header = new HashMap<>();
//hander.put("","");
return header;
}
private static String SoftVersion = "v1";//介面版本
private static String AppKey = "4bafd51*********************23fe";
private static String AppToken = "2e02b2***********************044";
private static String SecretKey = "HON************************HOU";
private static String Accept = "application/json";//接收的資料型別,如json、xml。
private static String code = "055************************c56"; //動態的使用者id
private static String str = "";
private static String str2 = "";
private static String str3 = "";
private static String str4 = "";
public static Map<String,String> getHeasers(){
Map<String,String> header = new HashMap<>();
String AppVersion = BaseRetrofitConfig.getAppVersionName(BaseApplication.context);
String AppName = BaseRetrofitConfig.getApplicationName(BaseApplication.context);
try {
str = EncryptUtil.base64Encoder(AppKey + ":" + AppToken + ":" + AppName + ":" + AppVersion + ":" + BaseRetrofitConfig.getTimestap());
str2 = EncryptUtil.base64Encoder(SoftVersion);
str3 = EncryptUtil.base64Encoder(code);
str4 = EncryptUtil.createSignature(AppKey, AppToken, SecretKey);
} catch (Exception e) {
System.err.println("app驗證錯誤!");
}
header.put("Accept", Accept);
header.put("AppInfo", str);
header.put("SoftVersion", str2);
header.put("accountSid", str3);
header.put("sig",str4);
return header;
}
/**
* 時間戳(只是伺服器做記錄)
* @return
*/
public static String getTimestap() {
return DateUtil.format(new Date(), DateUtil.PIN_PATTERN_DATE_MINUTE);
}
/**
* 返回當前版本名
*/
public static String getAppVersionName(Context context) {
String versionName = "";
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
versionName = pi.versionName;
if (versionName == null || versionName.length() <= 0) {
return "";
}
} catch (Exception e) {
Log.e("VersionInfo", "Exception", e);
e.printStackTrace();
}
return versionName;
}
/**
* 獲取當前應用名
* @param context
* @return
*/
public static String getApplicationName(Context context) {
PackageManager packageManager = null;
ApplicationInfo applicationInfo = null;
try {
packageManager = context.getPackageManager();
applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
applicationInfo = null;
}
String applicationName =
(String) packageManager.getApplicationLabel(applicationInfo);
return applicationName;
}
}
這個是重中之重,進行各種初始化,詳情請見註釋。通過builder模式初始化所用功能。
初始化retrofit,並加入日誌攔截、快取cookie、錯誤重連、超時時間、攔截新增header
並進行okhttp攔截。
package com.abysskitty.frame.network;
import com.abysskitty.frame.Switch;
import com.abysskitty.frame.base.BaseApplication;
import com.abysskitty.frame.network.cookie.CookieManger;
import com.abysskitty.frame.network.loggingInterceptors.okHttpLog.HttpLoggingInterceptorM;
import com.abysskitty.frame.network.loggingInterceptors.okHttpLog.LogInterceptor;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
/**
* Created by AbyssKitty on 2016/10/9.
* Version 1.0
* 初始化Retrofit 2.+
* 1.配置OkHttpClient、新增攔截器
* 2.新增HttpLoggingInterceptorM 日誌攔截
* 3.配置Retrofit
*/
public class BaseRetrofitFactory {
/**
* 新增header響應頭的集合,用於存放追加的header頭的資料
* */
private Map<String,String> map = new HashMap<>();
/**
* 自定義Interceptor物件,用於在網路請求發出之前將header攔截新增進響應頭
* */
private MyInterceptor myInterceptor = null;
/**
* 構造器,通過builder方式傳入header響應頭並初始化自定義攔截器Interceptor
* */
private BaseRetrofitFactory(Builder builder){
map.clear();
this.map = builder.map;
myInterceptor = new MyInterceptor(map);
}
/**
* okhttp的日誌攔截,可在正式釋出時關閉
* */
// private HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
/**
* 自定義okhttp的日誌攔截,可在正式釋出時關閉
* */
private HttpLoggingInterceptorM interceptorM = new HttpLoggingInterceptorM(new LogInterceptor()).setLevel(HttpLoggingInterceptorM.Level.BODY);
/**
* 建立自定義OkHttpClient物件,初始化日誌攔截、錯誤重連、超時、響應頭等資訊
* */
private OkHttpClient getClient(){
OkHttpClient client = null;
if(Switch.isDebug){
client = new OkHttpClient.Builder()
.addInterceptor(interceptorM) //日誌攔截
.cookieJar(new CookieManger(BaseApplication.context)) //快取cookie
.retryOnConnectionFailure(true) //錯誤重連
.connectTimeout(BaseRetrofitConfig.OKHTTP_OVERTIME, TimeUnit.SECONDS) //超時時間
.addNetworkInterceptor(myInterceptor) //攔截新增響應頭
.build();
}else{
client = new OkHttpClient.Builder()
.cookieJar(new CookieManger(BaseApplication.context)) //快取cookie
.retryOnConnectionFailure(true) //錯誤重連
.connectTimeout(BaseRetrofitConfig.OKHTTP_OVERTIME, TimeUnit.SECONDS) //超時時間
.addNetworkInterceptor(myInterceptor) //攔截新增響應頭
.build();
}
return client;
}
/**
* 初始化Retrofit物件,包括baseUrl、使用Gson解析、是用RxJava等。
* */
private Retrofit getRetrofit(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BaseRetrofitConfig.baseUrl) //base地址
.addConverterFactory(ScalarsConverterFactory.create()) //新增解析方式為String
.addConverterFactory(GsonConverterFactory.create()) //新增解析方式為Gson
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //新增網路RxJava
.client(getClient()) //新增自定義OkHttpClient
.build();
return retrofit;
}
/**
* 建立Retrofit例項
* */
public BaseRetrofitTwoService getRetrofitService(){
BaseRetrofitTwoService service = getRetrofit().create(BaseRetrofitTwoService.class);
return service;
}
/**
* Builder
* */
public static class Builder{
Map<String,String> map = new HashMap<>();
public Builder setHeaders(Map<String,String> map){
this.map = map;
return this;
}
public BaseRetrofitFactory build(){
return new BaseRetrofitFactory(this);
}
}
/**
* create by AbyssKitty on 2016/10/09.
* Version 1.0
* 每次ping 攜帶請求頭 從OkHttp中攔截,Retrofit2只能使用註解方式新增headers
* */
public class MyInterceptor implements Interceptor {
private Map<String, String> headers;
public MyInterceptor(Map<String, String> headers) {
this.headers = headers;
}
@Override
public Response intercept(Chain chain) throws IOException {
Response response = null;
//同步 避免溢位
synchronized (this){
Request.Builder builder = chain.request()
.newBuilder();
if (headers != null && headers.size() > 0) {
Set<String> keys = headers.keySet();
for (String headerKey : keys) {
builder.addHeader(headerKey, headers.get(headerKey)).build();
}
try{
response = chain.proceed(builder.build());
}catch (SocketTimeoutException e){
e.getLocalizedMessage();
}
}else{
response = chain.proceed(builder.build());
}
}
// 獲取error code 暫時不用
// Response responseError = chain.proceed(chain.request());
// responseError.code();
return response;
}
}
}
把Retrofit的介面集合化使用,集合成一個介面,複用高效。
package com.abysskitty.frame.network;
import java.util.Map;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.QueryMap;
import retrofit2.http.Streaming;
import retrofit2.http.Url;
import rx.Observable;
/**
* Created by AbyssKitty on 2016/10/6.
* Version 1.0
* 網路請求介面Retrofit 2.+
*/
public interface BaseRetrofitTwoService {
/**
* create by AbyssKitty on 2016/10/06.
* 以get方式的網路請求介面
* @param url 可傳全路徑或者只傳baseUrl之後的路徑
* @param map 鍵值對引數
* */
@GET("")
Observable<String> get(@Url String url, @QueryMap Map<String, String> map);
/**
* create by AbyssKitty on 2016/10/06.
* 以post方式的網路請求介面
* @param url 可傳全路徑或者只傳baseUrl之後的路徑
* @param map 鍵值對引數
* */
@POST("")
Observable<String> post(@Url String url, @QueryMap Map<String, String> map);
/**
* post實體
* */
@POST("")
Observable<String> postBody(@Url String url, @Body String body);
/**
* post表單
* */
@FormUrlEncoded
@POST("")
Observable<String> postField(@Url String url, @FieldMap Map<String, String> map);
/**
* 單圖上傳
* */
@Multipart
@POST("")
Observable<String> upLoadFile(
@Url String url,
@Part MultipartBody.Part file
);
/**
* 測試中 多圖上傳
* */
@Multipart
@POST("")
Observable<String> uploadFiles(
@Url String url,
@Part("filename") String description,
@PartMap() Map<String, RequestBody> maps);
/**
* 測試中 下載
* */
@Streaming
@GET
Observable<String> downloadFile(@Url String fileUrl);
}
自定義的Net操作類,簡單化呼叫過程
package com.abysskitty.frame.network;
import com.abysskitty.frame.network.bean.RespBean;
import com.google.gson.Gson;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Created by AbyssKitty on 2016/10/11.
* Version 1.0
* Net 自定義封裝
* 實現get post等方法,可在外部直接使用。
*/
public class NetModle<T> {
/* - resp裡的list - */
public final static int RESP_LIST = 0x560001;
/* - resp裡的obj - */
public final static int RESP_OBJ = 0x560002;
/* - resp裡的info - */
public final static int RESP_INFO = 0x560003;
/* - list - */
public final static int LIST = 0x560004;
/* - obj - */
public final static int OBJ = 0x560005;
/* - info - */
public final static int INFO = 0x560006;
/**
* 單例物件初始化,必須使用private修飾
* */
private NetModle(){}
/**
* 全域性handers
* */
private Map<String,String> map = new HashMap<>();
private Map<String,String> dmap = new HashMap<>();
/**
* Builder模式的初始化,保留
* */
private NetModle(Builder builder){
this.map = builder.map;
}
/**
* 獲取單例
* */
public static NetModle getInstance(){
return NetMoudleHolder.netModle;
}
/**
* 靜態內部類,實現執行緒安全、延遲載入、高效的單例模式。
* */
private static class NetMoudleHolder{
private static NetModle netModle = new NetModle();
}
/**
* get方式
* @param url 地址
* @param params 資料集合
* @param onNetSubscriberListener 回撥
* */
public void get(String url, Map<String,String> params , OnNetSubscriberListener onNetSubscriberListener){
get(url,params,0,null,onNetSubscriberListener);
}
/**
* @param url 地址
* @param params 資料集合
* @param type 返回的資料型別
* @param onNetSubscriberListener 回撥
* */
public void get(String url, Map<String,String> params, int type , OnNetSubscriberListener onNetSubscriberListener){
get(url,params,type,null,onNetSubscriberListener);
}
/**
* get方式
* @param url 地址
* @param params 資料集合
* @param type 返回的資料型別
* @param map 自定義的header集合
* @param onNetSubscriberListener 回撥
* */
public void get(String url, Map<String,String> params, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
//params = addParams(params);
getBaseRetrofitFactory(map)
.getRetrofitService()
.get(url,params)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(netNSListener(type,onNetSubscriberListener));
}
/**
* post方式
* @param url 地址
* @param params 資料集合
* @param onNetSubscriberListener 回撥
* */
public void post(String url, Map<String,String> params , OnNetSubscriberListener onNetSubscriberListener){
post(url,params,0,null,onNetSubscriberListener);
}
/**
* post方式
* @param url 地址
* @param params 資料集合
* @param type 返回的資料型別
* @param onNetSubscriberListener 回撥
* */
public void post(String url, Map<String,String> params, int type , OnNetSubscriberListener onNetSubscriberListener){
post(url,params,type,null,onNetSubscriberListener);
}
/**
* post方式
* @param url 地址
* @param params 資料集合
* @param type 返回的資料型別
* @param map 自定義的header集合,不傳的話使用預設的header
* @param onNetSubscriberListener 回撥
* */
public void post(String url, Map<String,String> params, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
//params = addParams(params);
getBaseRetrofitFactory(map)
.getRetrofitService()
.post(url,params)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(netNSListener(type,onNetSubscriberListener));
}
/**
* post傳實體
* */
public void postBody(String url, String json, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
// RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"),json);
// if(body != null){
// LogUtil.d("-----------------------------1"+body.toString());
//
// }else{
// LogUtil.d("-----------------------------2");
// }
getBaseRetrofitFactory(map)
.getRetrofitService()
.postBody(url,json)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(netNSListener(type,onNetSubscriberListener));
}
/**
* post傳表單FieldMap
* */
public void postField(String url, Map<String,String> parme, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
getBaseRetrofitFactory(map)
.getRetrofitService()
.postField(url,parme)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(netNSListener(type,onNetSubscriberListener));
}
/**
* 圖片上傳post方式
* @param url 地址
* @param path 圖片地址
* @param onNetSubscriberListener 回撥
* */
public void upload(String url, String path, OnNetSubscriberListener onNetSubscriberListener){
upload(url,path,0,null,onNetSubscriberListener);
}
/**
* 圖片上傳post方式
* @param url 地址
* @param path 圖片地址
* @param type 返回的資料型別
* @param map 自定義的header集合,不傳的話使用預設的header
* @param onNetSubscriberListener 回撥
* */
public void upload(String url, String path, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
//Subscription d =
getBaseRetrofitFactory(map)
.getRetrofitService()
.upLoadFile(url,getMultipartBodyPart(path))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(netNSListener(type,onNetSubscriberListener));
}
/**
* 圖片上傳post方式
* @param url 地址
* @param file 圖片檔案
* @param type 返回的資料型別
* @param map 自定義的header集合,不傳的話使用預設的header
* @param onNetSubscriberListener 回撥
* */
public void upload(String url, File file, int type, Map<String,String> map, OnNetSubscriberListener onNetSubscriberListener){
//Subscription d =
getBaseRetrofitFactory(map)
.getRetrofitService()
.upLoadFile(url,getMultipartBodyPart(file))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(netNSListener(type,onNetSubscriberListener));
}
/**
* Subscriber 預處理
* */
private Subscriber netNSListener(final int type, final OnNetSubscriberListener onNetSubscriberListener){
NetSubscriber<String> stringSubscriber = new NetSubscriber<String>() {
@Override
public void onCompleted() {
super.onCompleted(); //執行預處理
// if(onNetSubscriberListener != null){
// onNetSubscriberListener.onCompleted();
// }
}
@Override
public void onError(Throwable e){
super.onError(e); //執行預處理
if(onNetSubscriberListener != null){
onNetSubscriberListener.onError(e);
}
}
@Override
public void onNext(String s){
super.onNext(s); //執行預處理
Gson gson = new Gson();
//去掉根節點 資料預處理,根據伺服器資料修改!!!
RespBean rb = gson.fromJson(s, RespBean.class);
// Object o = jsonGetObj(type,rb);
// if(onNetSubscriberListener != null){
// onNetSubscriberListener.onNext(rb,o);
if(onNetSubscriberListener != null){
onNetSubscriberListener.onNext(rb);
}
}
};
return stringSubscriber;
}
/**
* 初始資料預處理
* */
@Deprecated
public Object jsonGetObj(int type, RespBean rb){
Object o = null;
Gson gson = new Gson();
switch (type){
case RESP_LIST:
o = rb.resp.list;
break;
case RESP_INFO:
o = gson.toJson(rb.resp.info);
break;
case RESP_OBJ:
o = gson.toJson(rb.resp.obj);
break;
case LIST:
o = rb.list;
break;
case INFO:
o = gson.toJson(rb.info);
break;
case OBJ:
o = gson.toJson(rb.obj);
break;
default:
}
return o;
}
/**
* 檔案上傳
* */
private MultipartBody.Part getMultipartBodyPart(String mPath){
File file = new File(mPath);
//multipart/form-data 格式
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
//file - 為上傳引數的 鍵名
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", file.getName(), requestFile);
return body;
}
/**
* 檔案上傳
* */
private MultipartBody.Part getMultipartBodyPart(File file){
//multipart/form-data 格式
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
//file - 為上傳引數的 鍵名
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", file.getName(), requestFile);
return body;
}
/**
* 獲取RetrofitFactory物件
* */
private BaseRetrofitFactory getBaseRetrofitFactory(Map<String,String> map){
BaseRetrofitFactory baseRetrofitFactory = null;
if(map != null){
baseRetrofitFactory = new BaseRetrofitFactory.Builder()
.setHeaders(map)
.build();
}else{
/* 在這裡新增預設的 handers */
dmap = BaseRetrofitConfig.getHanderCommonParameter();
//LogUtil.d("getHanderCommonParameter="+dmap.size()+" moren");
baseRetrofitFactory = new BaseRetrofitFactory.Builder()
.setHeaders(dmap)
.build();
}
return baseRetrofitFactory;
}
/**
* 追加params資料
* 可不用此方法,已摒棄
* */
@Deprecated
private Map addParams(Map parame){
Map<String,String> p = null;
p = BaseRetrofitConfig.getCommonParameter();
if(p != null){
parame.putAll(p);
}
return parame;
}
/**
* Builder,留用 暫時未用 ,當前是以靜態方法方式實現的
* */
public class Builder{
Map<String,String> map;
Map<String,String> params;
public Builder setHander(Map<String,String> map){
this.map = map;
return this;
}
public Builder setMap(Map<String,String> params){
this.params = params;
return this;
}
public NetModle build(){
return new NetModle(this);
}
}
}