android post请求添加公共参数_XHttp2 一个功能强悍的网络请求库
XHttp2
一個功能強悍的網絡請求庫,使用RxJava2 + Retrofit2 + OKHttp組合進行封裝。還不趕緊點擊使用說明文檔,體驗一下吧!
項目地址
關于我
https://github.com/xuexiangjys
特征
- 支持默認、全局、局部三個層次的配置功能。
- 支持動態配置和自定義底層框架Okhttpclient、Retrofit.
- 加入基礎ApiService,減少Api冗余。
- 支持多種方式訪問網絡GET、POST、PUT、DELETE等請求協議。
- 支持網絡緩存,六種緩存策略可選,涵蓋大多數業務場景。
- 支持固定添加header和動態添加header。
- 支持添加全局參數和動態添加局部參數。
- 支持文件下載、多文件上傳和表單提交數據。
- 支持文件請求、上傳、下載的進度回調、錯誤回調,也可以自定義回調。
- 支持任意數據結構的自動解析。
- 支持添加動態參數例如timeStamp時間戳、token、簽名sign。
- 支持自定義的擴展API。
- 支持多個請求合并。
- 支持Cookie管理。
- 支持異步、同步請求。
- 支持Https、自簽名網站Https的訪問、雙向驗證。
- 支持失敗重試機制,可以指定重試次數、重試間隔時間。
- 支持根據key刪除網絡緩存和清空網絡緩存。
- 提供默認的標準ApiResult(遵循OpenApi格式)解析和回調,并且可自定義ApiResult。
- 支持取消數據請求,取消訂閱,帶有對話框的請求不需要手動取消請求,對話框消失會自動取消請求。
- 支持請求數據結果采用回調和訂閱兩種方式。
- 提供"默認API"、"接口協議"以及"統一請求實體"三種方式進行網絡請求,支持自定義網絡請求協議。
- 返回結果和異常統一處理,支持自定義異常處理。
- 結合RxJava,線程切換靈活。
- 請求實體支持注解配置,配置網絡請求接口的url、是否需要驗證token以及請求參數的key。
- 擁有統一的網絡請求取消機制。
1、演示(請star支持)
1.1、Demo演示動畫
1.2、Demo下載
1.3、api服務安裝
服務端的搭建詳細請點擊查看
2、如何使用
目前支持主流開發工具AndroidStudio的使用,直接配置build.gradle,增加依賴即可.
2.1、Android Studio導入方法,添加Gradle依賴
1.先在項目根目錄的 build.gradle 的 repositories 添加:
allprojects {repositories {...maven { url "https://jitpack.io" }}
}2.然后在dependencies添加:
dependencies {...implementation 'com.github.xuexiangjys:XHttp2:1.0.2'implementation 'com.google.code.gson:gson:2.8.2'implementation 'com.squareup.okhttp3:okhttp:3.10.0'implementation 'io.reactivex.rxjava2:rxjava:2.1.12'implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
}3.在Application中初始化XHttpSDK
XHttpSDK.init(this); //初始化網絡請求框架,必須首先執行
XHttpSDK.debug("XHttp"); //需要調試的時候執行
XHttpSDK.setBaseUrl(SettingSPUtils.getInstance().getApiURL()); //設置網絡請求的基礎地址4.全局初始化配置(非必要)
除了上述的操作以外,你還可以使用XHttp.getInstance()對網絡請求框架進行全局性參數配置,配置一些公用默認的參數,這樣我們就不需要為每個請求都進行設置。方法如下:
方法名 | 備注 :-|:- debug | 設置日志的打印模式 setBaseUrl | 設置全局baseUrl setSubUrl | 設置全局subUrl setReadTimeOut | 設置全局讀取超時時間 setWriteTimeOut | 設置全局寫入超時時間 setConnectTimeout | 設置全局連接超時時間 setTimeout | 設置全局超時時間 setRetryCount | 設置全局超時重試次數 setRetryDelay | 設置全局超時重試延遲時間 setRetryIncreaseDelay | 設置全局超時重試延遲疊加時間 setCacheMode | 設置全局的緩存模式 setIsDiskCache | 設置是否是磁盤緩存 setMemoryMaxSize | 設置內存緩存的最大數量 setCacheTime | 設置全局的緩存過期時間 setCacheMaxSize | 設置全局的磁盤緩存大小,默認50M setCacheDirectory | 設置全局緩存的路徑,默認是應用包下面的緩存 setCacheDiskConverter | 設置全局緩存的轉換器 addCommonParams | 添加全局公共請求參數 addCommonHeaders | 添加全局公共請求參數 addInterceptor | 添加全局攔截器 addNetworkInterceptor | 添加全局網絡攔截器 setOkproxy | 全局設置OkHttpClient的代理 setOkconnectionPool | 設置全局OkHttpClient的請求連接池 setOkclient | 全局為Retrofit設置自定義的OkHttpClient addConverterFactory | 設置全局Converter.Factory,默認GsonConverterFactory.create() addCallAdapterFactory | 設置全局CallAdapter.Factory,默認RxJavaCallAdapterFactory.create() setHostnameVerifier | 設置https的全局訪問規則 setCertificates | 設置https的全局自簽名證書 setCookieStore | 設置全局cookie存取規則
如何進行網絡請求
需要注意的是,所以請求返回的結果必須要滿足以下格式:
{"Code":0, //響應碼,0為成功,否則失敗"Msg":"", //請求失敗的原因說明"Data":{} //返回的數據對象
}約定了其中Code、Msg、Data首字母必須大寫,否則無法解析成功。
需要自定義返回的實體API請點擊查看
1、使用XHttp默認api進行請求
1.使用XHttp.post、XHttp.get、XHttp.delete、XHttp.put、XHttp.downLoad構建請求。
2.修改request的請求參數。
方法名 | 類型 | 默認值 | 備注 :-|:-:|:-:|:- baseUrl | String | / | 設置該請求的baseUrl timeOut | long | 10000 | 設置超時時間 accessToken | boolean | false | 是否需要驗證token threadType | String | / | 設置請求的線程調度類型 syncRequest | boolean | false | 設置是否是同步請求(不開子線程) onMainThread | boolean | true | 請求完成后是否回到主線程 upJson | String | "" | 上傳Json格式的數據請求 keepJson | boolean | false | 返回保持json的形式 retryCount | int | / | 設置超時重試的次數 retryDelay | int | / | 設置超時重試的延遲時間 retryIncreaseDelay | int | / | 設置超時重試疊加延時 headers | HttpHeaders | / | 添加頭信息 params | HttpParams | /| 設置表單請求參數 cacheMode | CacheMode | CacheMode.NO_CACHE | 設置緩存的模式
3.調用execute方法執行請求。execute一般有如下兩種方式:
- execute(CallBack callBack): 直接回調結果。
- execute(Class clazz)和execute(Type type): 回調Observable對象,可通過訂閱獲取到結果。
4.請求使用演示
XHttp.get("/user/getAllUser").syncRequest(false) //異步請求.onMainThread(true) //回到主線程.execute(new SimpleCallBack<List<User>>() {@Overridepublic void onSuccess(List<User> response) {refreshLayout.finishRefresh(true);if (response != null && response.size() > 0) {mUserAdapter.refresh(response);mLlStateful.showContent();} else {mLlStateful.showEmpty();}}@Overridepublic void onError(ApiException e) {refreshLayout.finishRefresh(false);mLlStateful.showError(e.getMessage(), null);}});
XHttp.post("/user/deleteUser").params("userId", item.getUserId()).execute(Boolean.class).subscribeWith(new TipRequestSubscriber<Boolean>() {@Overrideprotected void onSuccess(Boolean aBoolean) {ToastUtils.toast("刪除成功!");setFragmentResult(RESULT_OK, null);popToBack();}});2、使用XHttpRequest封裝的統一請求實體進行請求【僅支持post請求】
在使用它之前,需要下載/定義對應的實體協議,如下:
@RequestParams(url = "/user/addUser", accessToken = false)
public static class UserService_AddUser extends XHttpRequest {/****/public User request;@Overrideprotected Boolean getResponseEntityType() {return null;}
}1.注解說明
- @RequestParams
注解參數 | 類型 | 默認值 | 備注 :-|:-:|:-:|:- baseUrl | String | "" | 設置該請求的baseUrl url | String | "" | 請求網絡接口地址 timeout | long | 15000 | 設置超時時間 accessToken | boolean | true | 設置是否需要驗證token cacheMode | CacheMode | CacheMode.NO_CACHE | 設置請求的緩存模式
- @ParamKey
注解參數 | 類型 | 默認值 | 備注 :-|:-:|:-:|:- key | String | / | 請求參數的key
2.使用XHttpSDK進行請求。
- post(XHttpRequest xHttpRequest, boolean isSyncRequest, boolean toMainThread): 獲取PostRequest請求(使用實體參數名作為請求Key)。
- postToMain(XHttpRequest xHttpRequest): 獲取PostRequest請求(主線程->主線程)。
- postToIO(XHttpRequest xHttpRequest): 獲取PostRequest請求(主線程->子線程)。
- postInThread(XHttpRequest xHttpRequest): 獲取PostRequest請求(子線程->子線程)。
- execute(XHttpRequest xHttpRequest, boolean isSyncRequest, boolean toMainThread) : 執行PostRequest請求,返回observable對象(使用實體參數名作為請求Key)。
executeToMain(XHttpRequest xHttpRequest): 執行post請求,返回observable對象(主線程->主線程)executeToMain(XHttpRequest xHttpRequest,BaseSubscriber<T> subscriber): 執行post請求并進行訂閱,返回訂閱信息(主線程->主線程)
3.請求使用演示。
XHttpRequest req = ApiProvider.getAddUserReq(getRandomUser());
XHttpSDK.executeToMain(req, new ProgressLoadingSubscriber<Boolean>(mIProgressLoader) {@Overridepublic void onSuccess(Boolean aBoolean) {ToastUtils.toast("用戶添加成功!");mRefreshLayout.autoRefresh();}
});3、使用XHttpProxy代理進行請求【僅支持post請求】
在使用它之前,需要下載/定義對應的接口協議,如下:
/*** 訂單*/
public interface IOrder {/*** 購買書** @param bookId 用戶名* @param userId 密碼*/@NetMethod(ParameterNames = {"bookId", "userId", "number"}, Url = "/order/addOrder/")Observable<Boolean> buyBook(int bookId, int userId, int number);
}1.注解說明
- @NetMethod
注解參數 | 類型 | 默認值 | 備注 :-|:-:|:-:|:- ParameterNames | String[] | {} | 參數名集合 BaseUrl | String | "" | 設置該請求的baseUrl Url | String | "" | 請求網絡接口地址 Timeout | long | 10000 | 設置超時時間 AccessToken | boolean | true | 設置是否需要驗證token CacheMode | CacheMode | CacheMode.NO_CACHE | 設置請求的緩存模式
2.使用XHttpProxy進行請求。
構建一個XHttpProxy,將定義的api接口傳入后,直接調用接口進行請求。
構造XHttpProxy可以傳入isPostJson來決定請求是上傳json數據還是鍵值對數據, 默認是true,上傳json數據。
構造XHttpProxy可以傳入ThreadType,默認是ThreadType.TO_MAIN。
- TO_MAIN: executeToMain(main -> io -> main)
【注意】請確保網絡請求在主線程中【實質是異步請求(切換到io線程),且響應的線程又切換至主線程】
- TO_IO: executeToIO(main -> io -> io)
【注意】請確保網絡請求在主線程中【實質是異步請求(切換到io線程),不過響應的線程不變,還是之前請求的那個io線程】
- IN_THREAD: executeInThread(io -> io -> io)
【注意】請確保網絡請求在子線程中才可以使用該類型【實質是不做任何線程調度的同步請求】
3.請求使用演示。
//使用XHttpProxy進行接口代理請求
XHttpProxy.proxy(TestApi.IOrder.class).buyBook(mBookAdapter.getItem(position).getBookId(), UserManager.getInstance().getUser().getUserId(), 1).subscribeWith(new TipRequestSubscriber<Boolean>() {@Overridepublic void onSuccess(Boolean aBoolean) {ToastUtils.toast("圖書購買" + (aBoolean ? "成功" : "失敗") + "!");mRefreshLayout.autoRefresh();}});4、文件上傳和下載
1.文件上傳【multipart/form-data】
使用post的文件表單上傳。使用XHttp.post,然后使用params傳遞附帶的參數,使用uploadFile傳遞需要上傳的文件,使用示例如下:
mIProgressLoader.updateMessage("上傳中...");
XHttp.post("/book/uploadBookPicture").params("bookId", book.getBookId()).uploadFile("file", FileUtils.getFileByPath(mPicturePath), new IProgressResponseCallBack() {@Overridepublic void onResponseProgress(long bytesWritten, long contentLength, boolean done) {}}).execute(Boolean.class).compose(RxLifecycle.with(this).<Boolean>bindToLifecycle()).subscribeWith(new ProgressLoadingSubscriber<Boolean>(mIProgressLoader) {@Overridepublic void onSuccess(Boolean aBoolean) {mIsEditSuccess = true;ToastUtils.toast("圖片上傳" + (aBoolean ? "成功" : "失敗") + "!");}});2.文件下載
使用XHttp.downLoad,傳入下載的地址url、保存文件的路徑以及文件名即可完成文件的下載,使用示例如下:
XHttp.downLoad(BookAdapter.getBookImgUrl(book)).savePath(PathUtils.getExtPicturesPath()).execute(new DownloadProgressCallBack<String>() {@Overridepublic void onStart() {HProgressDialogUtils.showHorizontalProgressDialog(getContext(), "圖片下載中...", true);}@Overridepublic void onError(ApiException e) {ToastUtils.toast(e.getMessage());HProgressDialogUtils.cancel();}@Overridepublic void update(long bytesRead, long contentLength, boolean done) {HProgressDialogUtils.onLoading(contentLength, bytesRead); //更新進度條}@Overridepublic void onComplete(String path) {ToastUtils.toast("圖片下載成功, 保存路徑:" + path);HProgressDialogUtils.cancel();}});高階網絡請求操作
請求生命周期綁定
1.請求loading加載和請求生命周期綁定
在請求時,訂閱ProgressLoadingSubscriber或者ProgressLoadingCallBack,傳入請求消息加載者IProgressLoader,即可完成生命周期的綁定。示例如下:
XHttpRequest req = ApiProvider.getAddUserReq(getRandomUser());XHttpSDK.executeToMain(req, new ProgressLoadingSubscriber<Boolean>(mIProgressLoader) {@Overridepublic void onSuccess(Boolean aBoolean) {ToastUtils.toast("用戶添加成功!");mRefreshLayout.autoRefresh();}});2.網絡請求生命周期和Activity/Fragment生命周期綁定
(1)這里需要依賴一下RxUtil2
implementation 'com.github.xuexiangjys:rxutil2:1.1.2'(2)在所在的Activity的onCreate()下鎖定Activity.
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);RxLifecycle.injectRxLifecycle(this);
}(3)然后在請求中使用RxJava的compose的操作符進行綁定。
.compose(RxLifecycle.with(this).<Boolean>bindToLifecycle())攔截器
日志攔截器
(1)框架默認提供一個實現好的日志攔截器HttpLoggingInterceptor,通過XHttpSDK.debug("XHttp");就可以設置進去,它有5種打印模式
- NONE: 不打印log
- BASIC: 只打印"請求首行"和"響應首行"。
- HEADERS: 打印請求和響應的所有 Header
- PARAM: 只打印請求和響應參數
- BODY: 打印所有數據(默認是這種)
(2)如果需要對網絡請求的相關參數進行自定義記錄的話,可以繼承HttpLoggingInterceptor實現一個自己的網絡請求日志攔截器,重寫logForRequest和logForResponse兩個方法即可。
(3)設置自定義的日志攔截器.
XHttpSDK.debug(new CustomLoggingInterceptor());動態參數添加攔截器
有時候,我們需要對所有請求添加一些固定的請求參數,但是這些參數的值又是變化的,這個時候我們就需要動態添加請求參數【例如,請求的token、時間戳以及簽名等】
(1)繼承BaseDynamicInterceptor,實現updateDynamicParams方法,如下:
@Override
protected TreeMap<String, Object> updateDynamicParams(TreeMap<String, Object> dynamicMap) {if (isAccessToken()) {//是否添加tokendynamicMap.put("token", TokenManager.getInstance().getToken());}if (isSign()) {//是否添加簽名dynamicMap.put("sign", TokenManager.getInstance().getSign());}if (isTimeStamp()) {//是否添加請求時間戳dynamicMap.put("timeStamp", DateUtils.getNowMills());}return dynamicMap;//dynamicMap:是原有的全局參數+局部參數+新增的動態參數
}(2)設置動態參數添加攔截器。
XHttpSDK.addInterceptor(new CustomDynamicInterceptor()); //設置動態參數添加攔截器失效請求校驗攔截器
當服務端返回一些獨特的錯誤碼(一般是token校驗錯誤、失效,請求過于頻繁等),需要我們進行全局性的攔截捕獲,并作出相應的響應時,我們就需要定義一個特殊的攔截器求處理這些請求。
(1)繼承BaseExpiredInterceptor,實現isResponseExpired和responseExpired方法。
(2)設置失效請求校驗攔截器。
XHttpSDK.addInterceptor(new CustomExpiredInterceptor()); //請求失效校驗攔截器自定義API請求
自定義請求響應的API結構
如果你不想使用默認的ApiResult實體作為統一的服務端響應實體,比如說你想要下面的響應實體:
private int errorCode; //請求的錯誤碼
private String errorInfo; //請求錯誤的原因描述
private T result; //請求的結果
private long timeStamp; //服務端返回的時間戳(1)首先,繼承ApiResult實體,重寫其getCode、getMsg、isSuccess和getData方法。
(2)進行請求的時候使用execute(CallBackProxy)或者execute(CallClazzProxy方法進行請求
XHttp.get("/test/testCustomResult").execute(new CallBackProxy<CustomApiResult<Boolean>, Boolean>(new TipRequestCallBack<Boolean>() {@Overridepublic void onSuccess(Boolean response) throws Throwable {ToastUtils.toast("請求成功:" + response);}}){}); //千萬注意,這里的{}一定不能去掉,否則解析錯誤【注意】上面提示的{}一定不能去掉,否則解析錯誤, 會報"ApiResult.class.isAssignableFrom(cls) err!!"的錯誤。
如果你覺得寫一長串比較麻煩,你可以自定義請求繼承你需要的請求方式,例如這里是get請求,我們可以這樣寫:
public class CustomGetRequest extends GetRequest {public CustomGetRequest(String url) {super(url);}@Overridepublic <T> Observable<T> execute(Type type) {return execute(new CallClazzProxy<CustomApiResult<T>, T>(type) {});}@Overridepublic <T> Disposable execute(CallBack<T> callBack) {return execute(new CallBackProxy<CustomApiResult<T>, T>(callBack) {});}
}然后我們就可以用自定義的CustomGetRequest進行請求了,是不是簡化了很多呢。
new CustomGetRequest("/test/testCustomResult").execute(new TipRequestCallBack<Boolean>() {@Overridepublic void onSuccess(Boolean response) throws Throwable {ToastUtils.toast("請求成功:" + response);}});使用自定義的retrofit接口
如果你對retrofit接口情有獨鐘,我也提供了相應的api方便調用.
1.定義retrofit接口。例如我定義一個用戶添加的接口:
/*** 使用的是retrofit的接口定義*/
public interface UserService {@POST("/user/registerUser/")@Headers({"Content-Type: application/json", "Accept: application/json"})Observable<ApiResult<Boolean>> registerUser(@Body RequestBody jsonBody);@POST("/user/registerUser/")@Headers({"Content-Type: application/json", "Accept: application/json"})Observable<ApiResult> register(@Body RequestBody jsonBody);
}2.使用XHttp.custom()構建的CustomRequest進行請求,你可以使用apiCall和call進行請求。
- apiCall: 針對的是retrofit定義的接口,返回的是Observable>的情況。對于上面定義的第一個接口
registerUser。 - call: 針對的是retrofit定義的接口,返回的是Observable的情況。對于上面定義的第二個接口
register。
使用示例如下:
CustomRequest request = XHttp.custom();
request.apiCall(request.create(TestApi.UserService.class).registerUser(HttpUtils.getJsonRequestBody(UserManager.getInstance().getRandomUser()))).subscribeWith(new TipRequestSubscriber<Boolean>() {@Overrideprotected void onSuccess(Boolean aBoolean) {ToastUtils.toast("添加用戶成功!");}});
CustomRequest request = XHttp.custom();
request.call(request.create(TestApi.UserService.class).register(HttpUtils.getJsonRequestBody(UserManager.getInstance().getRandomUser()))).subscribeWith(new TipRequestSubscriber<ApiResult>() {@Overrideprotected void onSuccess(ApiResult apiResult) {ToastUtils.toast("添加用戶成功!");showResult(JsonUtil.toJson(apiResult));}});緩存策略
目前框架提供了如下8種緩存策略:
- NO_CACHE: 不使用緩存(默認方式)
- DEFAULT: 完全按照HTTP協議的默認緩存規則,走OKhttp的Cache緩存
- FIRST_REMOTE: 先請求網絡,請求網絡失敗后再加載緩存
- FIRST_CACHE: 先加載緩存,緩存沒有再去請求網絡
- ONLY_REMOTE: 僅加載網絡,但數據依然會被緩存
- ONLY_CACHE: 只讀取緩存
- CACHE_REMOTE: 先使用緩存,不管是否存在,仍然請求網絡,會回調兩次
- CACHE_REMOTE_DISTINCT: 先使用緩存,不管是否存在,仍然請求網絡,會先把緩存回調給你,等網絡請求回來發現數據是一樣的就不會再返回,否則再返回(這樣做的目的是防止數據是一樣的你也需要刷新界面)
對于緩存的實現,提供了磁盤緩存LruDiskCache和內存緩存LruMemoryCache兩種實現,默認使用的是磁盤緩存。
(1)可以先進行緩存的全局性配置,配置緩存的有效期、緩存大小,緩存路徑、序列化器等。
XHttp.getInstance().setIsDiskCache(true) //設置使用磁盤緩存.setCacheTime(60 * 1000) //設置全局緩存有效期為一分鐘.setCacheVersion(1) //設置全局緩存的版本.setCacheDirectory(Utils.getDiskCacheDir(this, "XHttp")) //設置全局緩存保存的目錄路徑.setCacheMode(CacheMode.NO_CACHE) //設置全局的緩存策略.setCacheDiskConverter(new GsonDiskConverter())//默認緩存使用序列化轉化.setCacheMaxSize(50 * 1024 * 1024);//設置緩存大小為50M(2)在進行請求的時候,設置緩存模式和緩存的key即可。如下:
XHttp.get("/book/getAllBook").timeOut(10 * 1000)//測試局部超時10s.cacheMode(mCacheMode).cacheKey(CACHE_KEY)//緩存key.retryCount(5)//重試次數.cacheTime(5 * 60)//緩存時間300s,默認-1永久緩存 okhttp和自定義緩存都起作用.cacheDiskConverter(new GsonDiskConverter())//默認使用的是 new SerializableDiskConverter();.timeStamp(true).execute(new ProgressLoadingCallBack<CacheResult<List<Book>>>(mIProgressLoader) {@Overridepublic void onSuccess(CacheResult<List<Book>> cacheResult) {ToastUtils.toast("請求成功!");String from;if (cacheResult.isFromCache) {from = "我來自緩存";} else {from = "我來自遠程網絡";}showResult(from + "n" + JsonUtil.toJson(cacheResult.data));}@Overridepublic void onError(ApiException e) {super.onError(e);ToastUtils.toast(e.getDisplayMessage());}});混淆配置
#XHttp2
-keep class com.xuexiang.xhttp2.model.** { *; }
-keep class com.xuexiang.xhttp2.cache.model.** { *; }
-keep class com.xuexiang.xhttp2.cache.stategy.**{*;}
-keep class com.xuexiang.xhttp2.annotation.** { *; }#okhttp
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
-dontwarn javax.annotation.**# Retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Exceptions# RxJava RxAndroid
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {long producerIndex;long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {rx.internal.util.atomic.LinkedQueueNode consumerNode;
}#如果用到Gson解析包的,直接添加下面這幾行就能成功混淆,不然會報錯
-keepattributes Signature
-keep class com.google.gson.stream.** { *; }
-keepattributes EnclosingMethod
-keep class org.xz_sale.entity.**{*;}
-keep class com.google.gson.** {*;}
-keep class com.google.**{*;}
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }特別感謝
https://github.com/zhou-you/RxEasyHttp
聯系方式
新手提問前,請先閱讀【提問的智慧】
總結
以上是生活随笔為你收集整理的android post请求添加公共参数_XHttp2 一个功能强悍的网络请求库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 刘开头的成语有哪些啊?
- 下一篇: 个性签名短句8个字