基于 RxJava2 、Retrofit2颤枪、Okhttp3 的封裝庫——RxPanda

項目地址

RxPanda汗捡,歡迎使用和 star,提出的問題我會及時回復(fù)并處理畏纲。

接入方式

dependencies {
    "com.pandaq:rxpanda:1.0.2"
}

RxPanda

基于 RxJava2 Retrofit2 Okhttp3 封裝的網(wǎng)絡(luò)庫扇住,處理了數(shù)據(jù)格式封裝春缕,gson 數(shù)據(jù)類型處理,gson 類解析空安全問題台囱,使用時推薦使用 Release Log 中的最新版本目前為 1.0.2版本淡溯。

1读整、支持解析數(shù)據(jù)殼 key 自定義
2簿训、支持接口單獨配置禁用脫殼返回接口定義的原始對象
3、支持多 host 校驗
4米间、支持日志格式化及并發(fā)按序輸出
5强品、支持 data 為基本數(shù)據(jù)類型
6、支持 int 類型 json 解析為 String 不會 0 變成 0.0
7屈糊、支持解析類型為 int的榛、Stringfloat逻锐、double夫晌、longBigDecima昧诱、EmptyData 時 json 字段缺失晓淀。解析為對象時自動使用默認值
8、支持 json 解析時解析類型為第七條中的類型但是返回為 null 時替換為配置的默認值
9盏档、兼容 PHP 接口 float凶掰、intdouble蜈亩、long 類型無值時后端未處理返回空字符串導(dǎo)致解析失敗
10懦窘、支持開發(fā)階段單接口返回模擬json數(shù)據(jù)(適用于脫離后端接口開發(fā),提高開發(fā)效率)

Release Log

  • 1.0.2: a稚配、修復(fù) int畅涂、float、double 類型數(shù)據(jù)空字符串不能補全的問題道川;b午衰、新增注解@MockJsondebug 模式下替換模擬數(shù)據(jù)功能
  • 1.0.0: a、修復(fù)全局設(shè)置請求超時時間無效愤惰,會被 CONFIG 的默認超時時間覆蓋問題苇经;b、默認超時時間與 okhttp 保持一致設(shè)置為 10s
  • 0.2.6: 升級 Retrofit 版本以達到支持 kotlin suspend 關(guān)鍵字宦言,配合協(xié)程使用
  • 0.2.5: Json 解析為對象時扇单,基本數(shù)據(jù)類型 null 值或缺失的情況下增加默認值兼容
  • 0.2.4: ApiException msg 空兼容性優(yōu)化
  • 0.2.3: 兼容 Number 類型 data,接口無數(shù)據(jù)時返回空字符串會解析報錯的問題
  • 0.2.2: 日志攔截器重復(fù)添加 bug 修復(fù)
  • 0.2.1: 新增 http 錯誤類型分組功能奠旺、retrofit 進行 post蜘澜、get 請求適配公共參數(shù)添加施流、日志打印通過攔截器添加的參數(shù)信息缺失問題
  • 0.2.0: 使用 LogPrinter 同步輸出并發(fā)請求日志,避免日志錯亂
  • 0.1.9: 兼容 boolean 類型的 data
  • 0.1.8: 兼容 Android 9.0 移除反射方式替換 GsonAdapter鄙信,改用注冊方式
  • 0.1.7:文件上傳下載支持
  • 0.1.6:fix 數(shù)字解析為 String 類型時變成 double 類型字符串(1 按 String 解析變?yōu)?1.0 bug)

基本用法

一瞪醋、全局配置推薦在 Application 初始化時配置


        val defValues = NullDataValue()
        defValues.defBoolean = false
        defValues.defDouble = -1.0
        defValues.defFloat = -0.0f
        defValues.defInt = -1
        defValues.defLong =0L
        defValues.defString = ""

        RxPanda.globalConfig()
                .baseUrl(ApiService.BASE_URL) //配置基礎(chǔ)域名
                .netInterceptor(new HttpLoggingInterceptor()
                        .setLevel(HttpLoggingInterceptor.Level.BODY)) //添加日志攔截器
                .apiSuccessCode(100L) // 數(shù)據(jù)殼解析時接口成功的狀態(tài)碼
                .hosts("http://192.168.0.107:8080") // 兼容另一個 host(默認只允許基礎(chǔ)域名接口訪問)
                .connectTimeout(10000) // 連接超時時間(ms)
                .readTimeout(10000) // 讀取超時時間(ms)
                .writeTimeout(10000) // 寫入超時時間(ms)
                .client(new OkHttpClient.Builder()) // 僅用作補充 OkHttpClient 配置
                .defaultValue(defValues) // gson 返回字段為 null 或 字段缺失時,解析實體對象的基本類型默認值配置
                .debug(BuildConfig.DEBUG);// 是否 dubug 模式(非 debug 模式不會輸出日志)

以上只是精簡的配置装诡,還可以通過 GlobalConfig 配置類進行更多的全局配置

全部配置

方法 說明 是否必須
baseUrl() 基礎(chǔ)域名配置 true
hosts(String... hosts) 添加信任域名未配置默認只允許 baseUrl 配置的地址 false
trustAllHost(boolean trustAll) 是否信任所有域名優(yōu)先級大于 hosts银受,配置此為 true 則信任所有 host 不管是否添加 false
hostVerifier(@NonNull HostnameVerifier verifier) 配置 Host 驗證規(guī)則對象,未配置默認為 SafeHostnameVerifier (與 hosts()鸦采、trustAllHost() 方法沖突宾巍,添加此配置后另兩個配置失效,驗證規(guī)則以此配置為準) false
addCallAdapterFactory(@NonNull CallAdapter.Factory factory) 添加 CallAdapterFactory 未添加默認值為 RxJava2CallAdapterFactory false
converterFactory(@NonNull Converter.Factory factory) 配置 ConverterFactory 未添加默認值為 PandaConvertFactory false
callFactory(@NonNull Call.Factory factory) 配置 CallFactory false
sslFactory(@NonNull SSLSocketFactory factory) 配置 SSLFactory 未添加則通過 SSLManager 配置一個初始參數(shù)全為 null 的默認對象 false
connectionPool(@NonNull ConnectionPool pool) 配置連接池渔伯,未配置則使用 Okhttp 默認 false
addGlobalHeader(@NonNull String key, String header) 添加一個全局的請求頭 false
globalHeader(@NonNull Map<String, String> headers) 設(shè)置全局請求頭顶霞,會將已有數(shù)據(jù)清除再添加 false
addGlobalParam(@NonNull String key, String param) 添加一個全局的請求參數(shù) false
globalParams(@NonNull Map<String, String> params) 設(shè)置全局請求參數(shù),會將已有數(shù)據(jù)清除再添加 false
retryDelayMillis(long retryDelay) 重試間隔時間 false
retryCount(int retryCount) 重試次數(shù) false
interceptor(@NonNull Interceptor interceptor) 添加全局攔截器 false
netInterceptor(@NonNull Interceptor interceptor) 添加全局網(wǎng)絡(luò)攔截器 false
readTimeout(long readTimeout) 全局讀取超時時間 false
writeTimeout(long writeTimeout) 全局寫超時時間 false
connectTimeout(long connectTimeout) 全局連接超時時間 false
apiDataClazz(Class<? extends IApiData> clazz) Json解析接口數(shù)據(jù)結(jié)構(gòu)外殼對象 參考 ApiData锣吼,未配置默認按 ApiData 解析选浑,如結(jié)構(gòu)不變 key 不一致則可以通過自定義 false
apiSuccessCode(Long apiSuccessCode) Json解析接口數(shù)據(jù)結(jié)構(gòu)外殼對象為 ApiData 結(jié)構(gòu)時,配置成功 Code玄叠,默認值為 0L false
debug(boolean debug) 配置是否為 debug 模式古徒,非 debug 模式網(wǎng)絡(luò)庫將不會輸出 日志 false
defaultValue(NullDataValue defaultValue) 配置對應(yīng)數(shù)據(jù)類型返回結(jié)果為 null 或?qū)?yīng)數(shù)據(jù)接口未返回時的默認值 false
client(new OkHttpClient.Builder()) 補充配置 OkHttpClient,相同的配置會被 RxPanda 配置項覆蓋诸典,例如超時時長等 false

二描函、接口定義

    //使用全局配置的數(shù)據(jù)殼,默認為 ApiData
    @GET("xxx/xxx/xxx")
    Observable<List<ZooData>> getZooList();

與 retrofit 完全一樣的基礎(chǔ)上增加了兩個自定義注解

  • 1、 @RealEntity
    接口數(shù)據(jù)未使用 ApiData 進行數(shù)據(jù)殼包裝狐粱,需要直接解析未定義對象時使用舀寓。如上面代碼中的 ZhihuData 在解析時不會進行脫殼操作,接口返回 ZhihuData 就解析為 ZhihuData
        // 與 ApiData 結(jié)構(gòu)完全不一樣使用 RealEntity 標準不做脫殼處理肌蜻,返回 ZhihuData 就解析為 ZhihuData
        @RealEntity
        @GET("xxx/xxx/xxx")
        Observable<ZhihuData> zhihu();
    
  • 2互墓、@ApiData(clazz = ZooApiData.class)
    接口數(shù)據(jù)使用 ApiData 進行數(shù)據(jù)殼包裝,但包裝的 key 與默認的 ApiData 不一致時蒋搜,可自定義數(shù)數(shù)據(jù)殼實現(xiàn) IApiData 接口
// 自定義解析 key
data class ZooApiData<T>(
    @SerializedName("errorCode") private val code: Long,
    @SerializedName("errorMsg") private val msg: String,
    @SerializedName("response") private val data: T
) : IApiData<T> {
    override fun getCode(): Long {
        return code
    }

    override fun getMsg(): String {
        return msg
    }

    override fun getData(): T {
        return data
    }

    override fun isSuccess(): Boolean {
        return code.toInt() == 100
    }

}

給特定接口指定解析殼

    // 數(shù)據(jù)結(jié)構(gòu)不變但是數(shù)據(jù)殼 jsonKey 與框架默認不一致時使用此注解篡撵,也可在 Config 配置全局使用此數(shù)據(jù)殼
    @ApiData(clazz = ZooApiData.class)
    @GET("xxx/xxx/xxx")
    Observable<List<ZooData>> newJsonKeyData();

如果全部接口都是按 ZooApiData 的解析 key 格式返回的數(shù)據(jù),也不用麻煩的每個接口都加注解。直接在第一步的配置中使用全局配置來配置全局的數(shù)據(jù)殼

  .apiDataClazz(ZooApiData::class.java)
  • 3豆挽、 @MockJson(json = jsonString)
    后端給出數(shù)據(jù)結(jié)構(gòu)但接口尚在開發(fā)時育谬,可通過此注解配置模擬數(shù)據(jù)(僅在 RxPanda debug 模式下有效)。使用時在對應(yīng)的接口上此注解指定返回的 json 字符串帮哈,任意請求一個可請求通的接口即可
    // 給這個接口指定模擬返回的 json 為 Constants.MOCK_JSON(僅當 RxPanda.globalConfig().isDebug()=true 時有效)膛檀,請求地址為任意能正常請求的地址即可
    @MockJson(json = Constants.MOCK_JSON)
    @GET("https://www.baidu.com")
    Observable<List<ZooData>> newJsonKeyData();

三、自動補全默認值數(shù)據(jù)實體對象

本地需要解析的 UserInfo 對象如下

public class UserInfo {
    private String userName;
    private String nickName;
    private Integer age;
    private String notExist;
}
// 接口返回的data
{
"code": 0,
"msg": "獲取成功",
"data": {
            "userName": "張三",
            "nickName": "二狗子",
            "age": "27"
        }
}

當接口返回的 json 缺少 notExits 時,解析結(jié)果的 UserInfo 對象中 notExist 中的值將是null咖刃。如果配置了defaultValue泳炉,則在解析后notExist 的值將會解析為 defaultValue 中的對應(yīng)值。

三嚎杨、請求使用

Retrofit 方式

    private val apiService = RxPanda.retrofit().create(ApiService::class.java)

                . . .

     apiService.zooList
                    .doOnSubscribe { t -> compositeDisposable.add(t) }
                    .compose(RxScheduler.sync())
                    .subscribe(object : ApiObserver<List<ZooData>>() {
                        override fun onSuccess(data: List<ZooData>?) {
                            // do something
                        }

                        override fun onError(e: ApiException?) {
                            // do something when error
                        }

                        override fun finished(success: Boolean) {
                            // do something when all finish
                        }
                    })

                . . .

Http 請求方式

此方式直接使用花鹅,不需要第二步的接口定義

  • GET 方式

這只是一個最簡例子,可以通過鏈式調(diào)用添加參數(shù) 請求頭 攔截器 標簽 等屬性

    RxPanda.get("https://www.xx.xx.xx/xx/xx/xx")
    .addParam(paramsMap)
    .tag("tags") // 可使用 RequestManager 根據(jù) tag 管理請求
    .request(object :ApiObserver<List<ZooData>>(){
        override fun onSuccess(data: List<ZooData>?) {
            // do something
        }

        override fun onError(e: ApiException?) {
            // do something when error
        }

        override fun finished(success: Boolean) {
            // do something when all finish
        }

    })
  • POST 方式

這只是一個最簡例子枫浙,可以通過鏈式調(diào)用添加參數(shù) 請求頭 攔截器 標簽 等屬性

                RxPanda.post("xxxxxx")
                    .addHeader("header", "value")
                    .urlParams("key", "value")
                    .tag("ss")
                    .request(object : AppCallBack<String>() {
                        override fun success(data: String?) {

                        }

                        override fun fail(code: Long?, msg: String?) {

                        }

                        override fun finish(success: Boolean) {

                        }

                    })

文件上傳

        RxPanda.upload("url")
            .addImageFile("key",file)
//            .addBytes("key",bytes)
//            .addStream("key",stream)
//            .addImageFile("key",file)
            .request(object : UploadCallBack() {
                override fun done(success: Boolean) {

                }

                override fun onFailed(e: Exception?) {

                }

                override fun inProgress(progress: Int) {

                }

            })

文件下載

        RxPanda.download("url")
            .target(file)
//            .target(path,fileName)
            .request(object : UploadCallBack() {
                override fun done(success: Boolean) {

                }

                override fun onFailed(e: Exception?) {

                }

                override fun inProgress(progress: Int) {

                }

            })

日志處理

  • 日志數(shù)據(jù)格式化
    以下是一次完整的網(wǎng)絡(luò)請求刨肃,包含了數(shù)據(jù)和請求的基本參數(shù)數(shù)據(jù)
2019-08-13 10:04:02.088 22957-23059/com.pandaq.sample D/RxPanda:
2019-08-13 10:04:02.088 22957-23059/com.pandaq.sample D/RxPanda: ╔════════════════════════  HTTP  START  ══════════════════════════
2019-08-13 10:04:02.088 22957-23059/com.pandaq.sample D/RxPanda: ║
2019-08-13 10:04:02.088 22957-23059/com.pandaq.sample D/RxPanda: ║==> GET https://www.easy-mock.com/mock/5cef4b3e651e4075bad237f8/example/customApiData http/1.1
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Host: www.easy-mock.com
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Connection: Keep-Alive
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Accept-Encoding: gzip
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║User-Agent: okhttp/3.10.0
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Info: GET
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║==> 200 OK https://www.easy-mock.com/mock/5cef4b3e651e4075bad237f8/example/customApiData (245ms)
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Server: Tengine
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Date: Tue, 13 Aug 2019 02:04:01 GMT
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Content-Type: application/json; charset=utf-8
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Content-Length: 495
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Connection: keep-alive
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║X-Request-Id: 71a77b24-9822-47df-94b1-fd477cfcdaa9
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Vary: Accept, Origin
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Rate-Limit-Remaining: 1
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Rate-Limit-Reset: 1565661842
2019-08-13 10:04:02.089 22957-23059/com.pandaq.sample D/RxPanda: ║Rate-Limit-Total: 2
2019-08-13 10:04:02.094 22957-23059/com.pandaq.sample D/RxPanda: ║
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║——————————————————JSON START——————————————————
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║ {
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║   "errorCode": 100,
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║   "errorMsg": "我是錯誤信息",
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║   "response": [
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║     {
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "zooId": 28,
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "name": "成都市動物園",
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "englishName": "chengdu zoo",
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "address": "中國·四川·成都·成華區(qū)昭覺寺南路234號",
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "tel": "028-83516953"
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║     },
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║     {
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "zooId": 28,
2019-08-13 10:04:02.095 22957-23059/com.pandaq.sample D/RxPanda: ║       "name": "北京市動物園",
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "englishName": "beijing zoo",
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "address": "中國·北京·北京·XX路XX號",
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "tel": "028-83316953"
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║     },
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║     {
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "zooId": 28,
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "name": "重慶市動物園",
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "englishName": "chongqing zoo",
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "address": "中國·重慶·重慶·XX路XX號",
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║       "tel": "028-83513353"
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║     }
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║   ]
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║ }
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║——————————————————JSON END———————————————————
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║Info: 495-byte body
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ║
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda: ╚════════════════════════  HTTP  END  ═══════════════════════════
2019-08-13 10:04:02.096 22957-23059/com.pandaq.sample D/RxPanda:
  • 多線程并發(fā)請求時日志輸出交錯錯亂的問題
    為了避免請求日志穿插問題,定義了 LogEntity 日志對象類自脯,將一次請求的各個階段的日志輸出暫存起來之景,到當次網(wǎng)絡(luò)請求結(jié)束時統(tǒng)一打印數(shù)據(jù)斤富,打印時使用了線程安全的 LogPrinter 類有序輸出膏潮。(因此上線一定要關(guān)閉 Log(一般使用第一步的 BuildConfig.DEBUG 來動態(tài)配置),日志的線程鎖會有性能損耗满力。)

Gson 解析處理

以 String 類型解析 TypeAdapter 為例焕参,其他處理可在 DefaultTypeAdapters 查看

    public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
        @Override
        public String read(JsonReader in) throws IOException {
            JsonToken peek = in.peek();
            if (peek == JsonToken.NULL) {
                in.nextNull();
                return "";
            }
            if (peek == JsonToken.NUMBER) {
                double dbNum = in.nextDouble();
                if (dbNum > Long.MAX_VALUE) {
                    return String.valueOf(dbNum);
                }
                // 如果是整數(shù)
                if (dbNum == (long) dbNum) {
                    return String.valueOf((long) dbNum);
                } else {
                    return String.valueOf(dbNum);
                }
            }
            /* coerce booleans to strings for backwards compatibility */
            if (peek == JsonToken.BOOLEAN) {
                return Boolean.toString(in.nextBoolean());
            }
            return in.nextString();
        }

        @Override
        public void write(JsonWriter out, String value) throws IOException {
            out.value(value);
        }
    };
  • number 類型轉(zhuǎn)解析為字符串 1"1.0" 的問題
    Gson 解析由于 Gson 庫默認的 ObjectTypeAdapter 中 Number 類型數(shù)據(jù)直接都解析為了 double 數(shù)據(jù)類型,因此會出現(xiàn)油额。當接口返回數(shù)據(jù)為 int 型叠纷,解析類中又定義為 String 類型的時候出現(xiàn) 1"1.0"的問題。
// 對 number 具體的類型進行判斷潦嘶,而不是一概而論的返回 double 類型
            if (peek == JsonToken.NUMBER) {
                double dbNum = in.nextDouble();
                if (dbNum > Long.MAX_VALUE) {
                    return String.valueOf(dbNum);
                }
                // 如果是整數(shù)
                if (dbNum == (long) dbNum) {
                    return String.valueOf((long) dbNum);
                } else {
                    return String.valueOf(dbNum);
                }
            }
  • 避免空指針問題
    重寫 String 類型的 TypeAdapter 在類型為 null 時返回 ""空字符串
// 對于空類型不直接返回 null 而是返回 "" 避免空指針
            if (peek == JsonToken.NULL) {
                in.nextNull();
                return "";
            }

混淆打包

混淆打包需添加如下的過濾規(guī)則

-keep @android.support.annotation.Keep class * {*;}

-keep class android.support.annotation.Keep

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <methods>;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <fields>;
}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <init>(...);
}

########### OkHttp3 ###########
-dontwarn okhttp3.logging.**
-keep class okhttp3.internal.**{*;}
-dontwarn okio.**

########### 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 ###########
-keep class com.google.gson.stream.** { *; }
-keepattributes EnclosingMethod
# Gson 自定義相關(guān)
-keep class com.pandaq.rxpanda.entity.**{*;}
-keep class com.pandaq.rxpanda.gsonadapter.**{*;}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涩嚣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掂僵,更是在濱河造成了極大的恐慌航厚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锰蓬,死亡現(xiàn)場離奇詭異幔睬,居然都是意外死亡,警方通過查閱死者的電腦和手機芹扭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門麻顶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舱卡,你說我怎么就攤上這事辅肾。” “怎么了轮锥?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵矫钓,是天一觀的道長。 經(jīng)常有香客問我,道長份汗,這世上最難降的妖魔是什么盈电? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮杯活,結(jié)果婚禮上匆帚,老公的妹妹穿的比我還像新娘。我一直安慰自己旁钧,他們只是感情好吸重,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著歪今,像睡著了一般嚎幸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寄猩,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天嫉晶,我揣著相機與錄音,去河邊找鬼田篇。 笑死替废,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的泊柬。 我是一名探鬼主播椎镣,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兽赁!你這毒婦竟也來了状答?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤刀崖,失蹤者是張志新(化名)和其女友劉穎惊科,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒲跨,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡译断,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了或悲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孙咪。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巡语,靈堂內(nèi)的尸體忽然破棺而出翎蹈,到底是詐尸還是另有隱情,我是刑警寧澤男公,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布荤堪,位于F島的核電站合陵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澄阳。R本人自食惡果不足惜拥知,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碎赢。 院中可真熱鬧低剔,春花似錦、人聲如沸肮塞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枕赵。三九已至猜欺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拷窜,已是汗流浹背开皿。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留装黑,地道東北人副瀑。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像恋谭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挽鞠,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容