1. 程式人生 > >RxHttp 完美適配Android 10/11 上傳/下載/進度監聽

RxHttp 完美適配Android 10/11 上傳/下載/進度監聽

# 1、前言 隨著Android 11的正式釋出,適配Android 10/11 分割槽儲存就更加的迫切了,因為Android 11開始,將強制開啟分割槽儲存,我們就無法再以絕對路徑的方式去讀寫非沙盒目錄下的檔案,為此,[RxHttp ](https://github.com/liujingxing/okhttp-RxHttp)在`2.4.0`版本中就正式適配了分割槽儲存,並且,可以非常優雅的實現檔案上傳/下載/進度監聽,三步即可搞懂任意請求。 老規矩,先看看請求三部曲 ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd222bde222e4f7d88e3f69e6eabd0be~tplv-k3u1fbpfcp-watermark.image) 如果你想了解RxHttp更過功能,請檢視以下系列文章 [RxHttp 2000+star,協程請求,僅需三步](https://juejin.im/post/6856550856796897287) [RxHttp 讓你眼前一亮的Http請求框架](https://juejin.im/post/6844904016380428302) ***gradle依賴*** ## 必須 ```java //使用kapt依賴rxhttp-compiler時必須 apply plugin: 'kotlin-kapt' android { //必須,java 8或更高 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'com.ljx.rxhttp:rxhttp:2.5.2' implementation 'com.squareup.okhttp3:okhttp:4.9.0' //rxhttp v2.2.2版本起,需要手動依賴okhttp kapt 'com.ljx.rxhttp:rxhttp-compiler:2.5.2' //生成RxHttp類,純Java專案,請使用annotationProcessor代替kapt } ``` ## 可選 ```java android { defaultConfig { javaCompileOptions { annotationProcessorOptions { arguments = [ //使用asXxx方法時必須,告知RxHttp你依賴的rxjava版本,可傳入rxjava2、rxjava3 rxhttp_rxjava: 'rxjava3', rxhttp_package: 'rxhttp' //非必須,指定RxHttp類包名 ] } } } } dependencies { implementation 'com.ljx.rxlife:rxlife-coroutine:2.0.1' //管理協程生命週期,頁面銷燬,關閉請求 //rxjava2 (RxJava2/Rxjava3二選一,使用asXxx方法時必須) implementation 'io.reactivex.rxjava2:rxjava:2.2.8' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.ljx.rxlife2:rxlife-rxjava:2.0.0' //管理RxJava2生命週期,頁面銷燬,關閉請求 //rxjava3 implementation 'io.reactivex.rxjava3:rxjava:3.0.6' implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' implementation 'com.ljx.rxlife3:rxlife-rxjava:3.0.0' //管理RxJava3生命週期,頁面銷燬,關閉請求 //非必須,根據自己需求選擇 RxHttp預設內建了GsonConverter implementation 'com.ljx.rxhttp:converter-fastjson:2.5.2' implementation 'com.ljx.rxhttp:converter-jackson:2.5.2' implementation 'com.ljx.rxhttp:converter-moshi:2.5.2' implementation 'com.ljx.rxhttp:converter-protobuf:2.5.2' implementation 'com.ljx.rxhttp:converter-simplexml:2.5.2' } ``` # 2、Android 10/11 分割槽儲存 當我們App的`targetSdkVersion`更改為28以上,並且執行在Android 10以上裝置時,我們無法再以絕對路徑的方式,去讀寫非沙盒目錄下的檔案,當然,如果App是覆蓋安裝(如:targetSdkVersion 28 覆蓋安裝為 29),則會保持原來的訪問方式。 ***requestLegacyExternalStorage屬性*** 如果我們的app將targetSdkVersion更改為28以上,且想保持原來的訪問方式,則需要在清單檔案中將 `requestLegacyExternalStorage` 的值設定為 `true`,如下: ```xml ``` 此時,便可繼續以原來的方式去讀寫檔案,然而,在Android 11上,Google又給了它新的含義,來看看[官網的原話](https://developer.android.google.cn/training/data-storage/use-cases#opt-out-scoped-storage) ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eea88335b9424484a4e85fa8bf1cb4dc~tplv-k3u1fbpfcp-watermark.image) 也就是說,在Android 11裝置上,`targetSdkVersion`為29以上的app,將強制開啟分割槽儲存,`requestLegacyExternalStorage`屬性失效 ***注意,只要同時滿足以上兩個條件,不管是覆蓋安裝還是`requestLegacyExternalStorage = true`,都會強制開啟分割槽儲存*** ***分割槽儲存優勢*** - 對使用者來說,解決了檔案亂放的現象 - 對於開發者來說,我們無需寫許可權,就可以在分割槽目錄下建立檔案,並且訪問自己建立的檔案,不需要讀許可權(訪問其它應用建立的檔案,還是需要讀許可權) ***新的檔案訪問方式*** ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f54452cb69f9425eb2b77dea7041efa6~tplv-k3u1fbpfcp-watermark.image) 此圖來源於作者[連續三屆村草]分享的[Android 10(Q)/11(R) 分割槽儲存適配](https://juejin.im/post/6862633674089693197#heading-2)一文,感謝作者的總結 # 3、上傳 ## 3.1、簡單上傳 在介紹Android 10檔案上傳前,我們先來看看Android 10之前是如何上傳檔案的,如下: ```java //kotlin 協程 val result = RxHttp.postForm("/service/...") .add("key", "value") .addFile("file", File("xxx/1.jpg")) .awaitString() //awaitXxx系列方法是結束通話方法 //RxJava RxHttp.postForm("/service/...") .add("key", "value") .addFile("file", File("xxx/1.jpg")) .asString() .subscribe({ //成功回撥 }, { //異常回調 }) ``` 以上,我們僅需呼叫 `addFile`方法新增檔案物件即可,RxHttp提供了一系列`addFile`方法,列出幾個常用的,如下: ```java //新增單個檔案 addFile(String, File) //新增多個檔案,每個檔案對應相同的key addFile(String, List fileList) //新增多個檔案,每個檔案對應不同的key add