寫這篇博客主要想記錄一下這個問題,我覺得大家應該都不會碰到,
在我之前的一篇文章Android Q:上傳圖片java.io.FileNotFoundException: open failed: EACCES (Permission denied) 中有說到,新安卓版本下,使用公共檔案資源不能夠File file = new File(path)了,需要使用FD,也就是FileDescriptor,現在,我這邊碰到了一個非常非常奇葩的問題,就如標題所示:
IOException read fail:EBADF (Bad file descriptor)
這個錯誤,是try-catch出來,然后Toast到螢屏上,截圖下來的,是不是這套操作,很奇怪,為什么我不debug?
這個錯誤,在debug環境下的安裝包,是不會報錯的,在release安裝包下,會報錯,在測驗機上會報錯,在我手機findx上不報錯,在上一個專案中用到,沒報過這個錯誤,在這個專案后期,碰到了這個錯誤,
非常奇葩,根本想不通,為什么同一套代碼,連介面地址都一樣,release包就報錯了,
我把功能代碼整合了一下,放上來
//現在假定,已經獲取到了一個資源的Uri 并且要上傳
private void update() throws IOException {
ParcelFileDescriptor parcelFileDescriptor = getApplication.getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
FileInputStream fis = new FileInputStream(fileDescriptor);
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[1024*4]; //buff用于存放回圈讀取的臨時資料
int rc = 0;
while ((rc = fis.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);//表單型別
RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), swapStream.toByteArray());//表單型別
builder.addFormDataPart("file", "xxx.mp4", body);
Retrofit.getApi.update(builder.build().parts())
.compose(做一些切換執行緒的操作,和資料處理)
.subscribe(new Observe{
//成功 失敗回呼
});
}
我那邊分好幾個檔案呼叫,但是整套流程大致就是這樣,獲取檔案byte[],構建formData檔案Retrofit上傳,呼叫介面,
呼叫的時候,你就需要try-catch,然后release環境下,我這邊就報錯了,
直接說解決辦法吧,因為我也不知道為什么會報錯,有知道的大佬可以提點一下我,由于我用的MVVM框架,而ViewModel中是不能持有activity的context的,但是可以有application,因此在使用getContentResolver(),我用的是application,當時我是把這代碼放在了MainActivity中測驗,發現居然不報錯,成功上傳了,對比下,只有在獲取getContentResolver()這個時候不一樣,
我把所有getContentResolver的地方都使用了activity的context,就沒有報這個錯誤了,就是代碼結構變化比較大,需要把獲取ParcelFileDescriptor放在View模塊執行,然后再到ViewModel中轉化成byte[],
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/231461.html
標籤:其他
上一篇:android10 Glide加載本地圖片不顯示的問題解決
下一篇:Android使用ListView中給控制元件設定了“android:clickable=“false“屬性,Item點擊依然沒有回呼
