Android阿里雲OSS多檔案同步上傳和刪除方案
上個專案中使用的是阿里雲OSS,查閱了官方文件,發現居然沒有多檔案上傳相關說明文件,只有一個單檔案非同步上傳的說明。既沒有多檔案上傳,又沒有同步上傳,刪除檔案亦然,凌亂。想到之前做過的七牛雲開發,決定用java遞迴的方式實現多檔案同步上傳和刪除,遞迴有風險,使用需謹慎哈。
阿里雲的配置和初始化官方已經說的很明白了,那麼這裡就直接了當說關鍵的:
一般來說我們都是獲得多檔案對應的本地地址List集合,然後遞迴每個url進行上傳 ---->
/** * 上傳多檔案 * * @param urls */ public void uploadFiles(List<String> urls) { if (null == urls || urls.size() == 0) { return; } // 上傳檔案 ossUpload(urls); }
下面是阿里雲上傳遞迴體----->
/** * 阿里雲OSS上傳(預設是非同步多檔案上傳) * @param urls */ private void ossUpload(final List<String> urls) { if (urls.size() <= 0) { // 檔案全部上傳完畢,這裡編寫上傳結束的邏輯,如果要在主執行緒操作,最好用Handler或runOnUiThead做對應邏輯 return;// 這個return必須有,否則下面報越界異常,原因自己思考下哈 } final String url = urls.get(0); if (TextUtils.isEmpty(url)) { urls.remove(0); // url為空就沒必要上傳了,這裡做的是跳過它繼續上傳的邏輯。 ossUpload(urls); return; } File file = new File(url); if (null == file || !file.exists()) { urls.remove(0); // 檔案為空或不存在就沒必要上傳了,這裡做的是跳過它繼續上傳的邏輯。 ossUpload(urls); return; } // 檔案字尾 String fileSuffix = ""; if (file.isFile()) { // 獲取檔案字尾名 fileSuffix = file.getName().substring(file.getName().lastIndexOf(".")); } // 檔案識別符號objectKey final String objectKey = "alioss_" + System.currentTimeMillis() + fileSuffix; // 下面3個引數依次為bucket名,ObjectKey名,上傳檔案路徑 PutObjectRequest put = new PutObjectRequest(Constant.BUCKET_NAME, objectKey, url); // 設定進度回撥 put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() { @Override public void onProgress(PutObjectRequest request, long currentSize, long totalSize) { // 進度邏輯 } }); // 非同步上傳 OSSAsyncTask task = MyApp.getOSS().asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() { @Override public void onSuccess(PutObjectRequest request, PutObjectResult result) { // 上傳成功 urls.remove(0); ossUpload(urls);// 遞迴同步效果 } @Override public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) { // 上傳失敗 // 請求異常 if (clientExcepion != null) { // 本地異常如網路異常等 clientExcepion.printStackTrace(); } if (serviceException != null) { // 服務異常 Log.e("ErrorCode", serviceException.getErrorCode()); Log.e("RequestId", serviceException.getRequestId()); Log.e("HostId", serviceException.getHostId()); Log.e("RawMessage", serviceException.getRawMessage()); } } }); // task.cancel(); // 可以取消任務 // task.waitUntilFinished(); // 可以等待直到任務完成 }
OK,看懂了沒,還是蠻簡單的,程式碼註釋的也很詳細。多檔案同步刪除與上述上傳邏輯屬於同一個套路,改幾個單詞差不多就可以了。這裡提醒下,阿里雲oss是根據objectKey刪除檔案的,所以判斷檔案存不存在是使用官方的程式碼判斷 :
boolean isExist = MyApp.getOSS().doesObjectExist(Constant.BUCKET_NAME, objectKey);
這次就不上傳原始碼了,大家有什麼疑問之處或需要原始碼可以直接回復我。
2017年8月3日更新:
很多朋友都在問我一個請求能不能同時上傳多張圖片,我這邊可能因為沒有深入地研究官方文件,不能給大家作出肯定的回覆。
But,個人認為沒有必要提供這樣的介面:首先,多圖片一個請求同時上傳需要消耗更多的CPU和記憶體資源(容易造成OOM);其次,漫長時間的網路連線,如果中間出現錯誤(網路,APP,系統出現問題)不僅前功盡棄,服務端還要刪除這些tmp檔案。
方案有沒有?
這裡提供簡單的方案思路(基於本文上傳方案的修改):
上文提到一個圖片上傳成功後會回撥OSSCompletedCallback的onSuccess方法,那麼我們可以在此記錄被上傳的圖片的objectKey於List或Map中,上傳結束後把這些objectKey集合通過一個請求反饋給App的服務端就可以了。
Excause Me?! 嗯!就這樣!