Commit f41a44c3f69d4af0998976eadd1271e6de29b375
1 parent
76084802
添加注释
Showing
4 changed files
with
439 additions
and
375 deletions
app/src/main/java/com/cnlive/cnUploadDemo/MultiUploader.java
| ... | ... | @@ -31,6 +31,7 @@ import java.util.Collections; |
| 31 | 31 | import java.util.HashSet; |
| 32 | 32 | import java.util.Iterator; |
| 33 | 33 | import java.util.List; |
| 34 | +import java.util.Set; | |
| 34 | 35 | import java.util.concurrent.atomic.AtomicInteger; |
| 35 | 36 | |
| 36 | 37 | /** |
| ... | ... | @@ -40,389 +41,239 @@ import java.util.concurrent.atomic.AtomicInteger; |
| 40 | 41 | */ |
| 41 | 42 | |
| 42 | 43 | public class MultiUploader { |
| 43 | - private static final String TAG = "MultiUploader"; | |
| 44 | + final private String TAG = "MultiUploader"; | |
| 44 | 45 | |
| 45 | - private String bucketName; | |
| 46 | 46 | private String key; |
| 47 | 47 | private File file; |
| 48 | - private int concurrentNo = 2; | |
| 49 | - private long partSize = 5 * 1024 * 1024; | |
| 48 | + private long partSize = 5 * 1024 * 1024; // 5MB | |
| 50 | 49 | private String uploadId; |
| 51 | - private AtomicInteger cur; | |
| 52 | 50 | private CNUpload cnUpload; |
| 51 | + final static private int INIT_DONE = 0; | |
| 52 | + final static private int PARTS_DONE = 1; | |
| 53 | + final static private int COMPLETE_DONE = 2; | |
| 54 | + final static private int GET_UPLOADED_DONE = 3; | |
| 53 | 55 | |
| 54 | - private static final int INIT_DONE = 0; | |
| 55 | - private static final int PARATS_DONE = 1; | |
| 56 | - private static final int COMPLETE_DONE = 2; | |
| 57 | - private static final int GET_UPLOADED_DONE = 3; | |
| 58 | - private static final int LIMIT_DONE = 4; | |
| 56 | + final List<CNPartETag> doneParts = Collections.synchronizedList(new ArrayList()); | |
| 59 | 57 | |
| 60 | - private boolean pause = false; | |
| 61 | - private boolean isAbortMultipartUpload = false; | |
| 62 | - | |
| 63 | - List<CNPartETag> doneParts = Collections.synchronizedList(new ArrayList<CNPartETag>()); | |
| 64 | - private List<Integer> leftParts = Collections.synchronizedList(new ArrayList<Integer>()); | |
| 65 | - private CNCompleteMultipartUploadResponseListener multiListener; | |
| 66 | - private final MyHandler mHandler = new MyHandler(); | |
| 67 | - | |
| 68 | - private void create(CNUpload cnUpload, File file, String uploadId, long partSize) { | |
| 58 | + private void create(CNUpload cnUpload, String key, File file, String uploadId, long partSize) { | |
| 69 | 59 | this.cnUpload = cnUpload; |
| 60 | + this.key = key; | |
| 70 | 61 | this.file = file; |
| 71 | 62 | this.uploadId = uploadId; |
| 72 | 63 | this.partSize = partSize; |
| 73 | 64 | } |
| 74 | 65 | |
| 75 | - public MultiUploader(CNUpload cnUpload, File file, String uploadId, long partSize) { | |
| 76 | - this.create(cnUpload, file, uploadId, partSize); | |
| 66 | + public MultiUploader(CNUpload cnUpload, String key, File file, String uploadId, long partSize) { | |
| 67 | + create(cnUpload, key, file, uploadId, partSize); | |
| 77 | 68 | } |
| 78 | 69 | |
| 79 | - public MultiUploader(CNUpload cnUpload, File file, String uploadId) { | |
| 80 | - this.create(cnUpload, file, uploadId, this.partSize); | |
| 70 | + public MultiUploader(CNUpload cnUpload, String key, File file, String uploadId) { | |
| 71 | + create(cnUpload, key, file, uploadId, partSize); | |
| 81 | 72 | } |
| 82 | 73 | |
| 83 | - public MultiUploader(CNUpload cnUpload, File file) { | |
| 84 | - this.create(cnUpload, file, null, this.partSize); | |
| 74 | + public MultiUploader(CNUpload cnUpload, String key, File file) { | |
| 75 | + create(cnUpload, key, file, null, partSize); | |
| 85 | 76 | } |
| 86 | 77 | |
| 87 | - public MultiUploader(CNUpload cnUpload, File file, long partSize) { | |
| 88 | - this.create(cnUpload, file, null, partSize); | |
| 78 | + public MultiUploader(CNUpload cnUpload, String key, File file, long partSize) { | |
| 79 | + create(cnUpload, key, file, null, partSize); | |
| 89 | 80 | } |
| 90 | 81 | |
| 91 | - /** | |
| 92 | - * 并发传的块数,默认就是2。一般不用改。根据你自测的性能状况来调整。 | |
| 93 | - * | |
| 94 | - * @param no | |
| 95 | - */ | |
| 96 | - public void setConcurrentNo(int no) { | |
| 97 | - this.concurrentNo = no; | |
| 82 | + public String getKey() { | |
| 83 | + return key; | |
| 98 | 84 | } |
| 99 | 85 | |
| 100 | - public void setListener(CNCompleteMultipartUploadResponseListener listener) { | |
| 101 | - this.multiListener = listener; | |
| 86 | + public String getUploadId() { | |
| 87 | + return uploadId; | |
| 102 | 88 | } |
| 103 | 89 | |
| 104 | - public String getKey() { | |
| 105 | - return this.key; | |
| 90 | + abstract class MyUploadPartResponceHandler implements CNUploadPartResponseListener { | |
| 91 | + private String key; | |
| 92 | + private int partNo; | |
| 93 | + private String uploadId; | |
| 94 | + | |
| 95 | + public abstract void onSuccess(int statesCode, Header[] responceHeaders, CNPartETag result, String key, int partNo, String uploadId); | |
| 96 | + | |
| 97 | + public abstract void onFailure(int statesCode, UploadError error, Header[] responceHeaders, String response, Throwable throwable | |
| 98 | + , String key, int partNo, String uploadId); | |
| 99 | + | |
| 100 | + public abstract void onTaskProgress(double progress, String key, int partNo, String uploadId); | |
| 101 | + | |
| 102 | + public MyUploadPartResponceHandler(String key, int partNo, String uploadId) { | |
| 103 | + this.key = key; | |
| 104 | + this.partNo = partNo; | |
| 105 | + this.uploadId = uploadId; | |
| 106 | + } | |
| 107 | + | |
| 108 | + @Override | |
| 109 | + public void onTaskProgress(double progress) { | |
| 110 | + onTaskProgress(progress, key, partNo, uploadId); | |
| 111 | + } | |
| 112 | + | |
| 113 | + @Override | |
| 114 | + public void onSuccess(int statesCode, Header[] responceHeaders, CNPartETag result) { | |
| 115 | + onSuccess(statesCode, responceHeaders, result, key, partNo, uploadId); | |
| 116 | + } | |
| 117 | + | |
| 118 | + @Override | |
| 119 | + public void onFailure(int statesCode, UploadError error, Header[] responceHeaders, String response, Throwable throwable) { | |
| 120 | + onFailure(statesCode, error, responceHeaders, response, throwable, key, partNo, uploadId); | |
| 121 | + } | |
| 106 | 122 | } |
| 107 | 123 | |
| 108 | - public String getUploadId() { | |
| 109 | - return this.uploadId; | |
| 124 | + private final MyHandler mHandler = new MyHandler(); | |
| 125 | + | |
| 126 | + class MyHandler extends Handler { | |
| 127 | + @Override | |
| 128 | + public void handleMessage(Message msg) { | |
| 129 | + switch (msg.what) { | |
| 130 | + case INIT_DONE: | |
| 131 | + uploadParts(); | |
| 132 | + break; | |
| 133 | + case PARTS_DONE: | |
| 134 | + completeUpload(); | |
| 135 | + break; | |
| 136 | + case GET_UPLOADED_DONE: | |
| 137 | + List<CNPartETag> res = (List<CNPartETag>) msg.obj; | |
| 138 | + reUpload(res); | |
| 139 | + break; | |
| 140 | + default: | |
| 141 | + break; | |
| 142 | + } | |
| 143 | + } | |
| 110 | 144 | } |
| 111 | 145 | |
| 112 | - /** | |
| 113 | - * 初始化分块上传 | |
| 114 | - * | |
| 115 | - * @param name 文件名 | |
| 116 | - * @param des 描述 | |
| 117 | - * @param userId 用户id | |
| 118 | - * @param filePath 文件路径 | |
| 119 | - * @param file 图片 | |
| 120 | - * @param isHorizontalScreen 横竖屏 | |
| 121 | - * @param callback 回到地址 | |
| 122 | - * @return | |
| 146 | + /* | |
| 147 | + return false, if uploadId hasbeen got | |
| 123 | 148 | */ |
| 124 | - public boolean upload(String name, String des, String userId, String filePath, File file, int isHorizontalScreen, String callback) { | |
| 125 | -// pause = false; | |
| 126 | - if (this.uploadId != null) { | |
| 127 | - return false; | |
| 128 | - } else { | |
| 129 | - isAbortMultipartUpload = false; | |
| 130 | - final CNInitiateMultipartUploadRequest request = new CNInitiateMultipartUploadRequest( key); | |
| 131 | - request.setCannedACL(CNCannedAccessControlList.PublicRead); | |
| 132 | - request.setContentType("video/mp4"); | |
| 133 | - cnUpload.initiateMultipartUpload(request, new CNInitiateMultipartUploadResponseListener() { | |
| 134 | - @Override | |
| 135 | - public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { | |
| 136 | - Log.w(TAG, "init multiupload fail, statusCode = " + i, throwable); | |
| 137 | - } | |
| 149 | + public boolean upload() { | |
| 150 | + if (uploadId != null) return false; | |
| 151 | + CNInitiateMultipartUploadRequest request = new CNInitiateMultipartUploadRequest(key); | |
| 152 | + cnUpload.initiateMultipartUpload(request, new CNInitiateMultipartUploadResponseListener() { | |
| 153 | + @Override | |
| 154 | + public void onFailure(int statesCode, UploadError error, Header[] responceHeaders, String response, Throwable paramThrowable) { | |
| 155 | + Log.w(TAG, "init multiupload fail, statesCode=" + statesCode, paramThrowable); | |
| 156 | + } | |
| 138 | 157 | |
| 139 | - @Override | |
| 140 | - public void onSuccess(int i, Header[] headers, CNInitiateMultipartUploadResult cnInitiateMultipartUploadResult) { | |
| 141 | - uploadId = cnInitiateMultipartUploadResult.getUploadId(); | |
| 142 | - Log.d(TAG, "init multiupload success, uploadId = " + uploadId + ", key = " + key + " : " + cnInitiateMultipartUploadResult.getBucket() + " : " + cnInitiateMultipartUploadResult.getKey()); | |
| 143 | - bucketName = cnInitiateMultipartUploadResult.getBucket(); | |
| 144 | - key = cnInitiateMultipartUploadResult.getKey(); | |
| 145 | - mHandler.sendEmptyMessage(INIT_DONE); | |
| 146 | - } | |
| 147 | - }); | |
| 148 | - return true; | |
| 149 | - } | |
| 158 | + @Override | |
| 159 | + public void onSuccess(int statesCode, Header[] responceHeaders, CNInitiateMultipartUploadResult result) { | |
| 160 | + uploadId = result.getUploadId(); | |
| 161 | + Log.d(TAG, "init multiupload success, uploadId=" + uploadId + ",key=" + key); | |
| 162 | + mHandler.sendEmptyMessage(INIT_DONE); | |
| 163 | + } | |
| 164 | + }); | |
| 165 | + return true; | |
| 150 | 166 | } |
| 151 | 167 | |
| 152 | 168 | private List<CNPartETag> convertPart(List<CNPart> list) { |
| 153 | - ArrayList res = new ArrayList(); | |
| 154 | - Iterator iterator = list.iterator(); | |
| 155 | - | |
| 156 | - while (iterator.hasNext()) { | |
| 157 | - CNPart part = (CNPart) iterator.next(); | |
| 158 | - res.add(new CNPartETag(part.getPartNumber(), part.getETag())); | |
| 169 | + List<CNPartETag> res = new ArrayList<CNPartETag>(); | |
| 170 | + for (CNPart p : list) { | |
| 171 | + res.add(new CNPartETag(p.getPartNumber(), p.getETag())); | |
| 159 | 172 | } |
| 160 | 173 | return res; |
| 161 | 174 | } |
| 162 | 175 | |
| 163 | - /** | |
| 164 | - * 罗列出已经上传的块 | |
| 176 | + /* | |
| 177 | + Get from ks3 server. call list parts API. | |
| 165 | 178 | */ |
| 166 | 179 | public void getUploadedParts() { |
| 167 | - final ArrayList res = new ArrayList(); | |
| 168 | - CNListPartsResponseListener listener = new CNListPartsResponseListener() { | |
| 180 | + final List<CNPartETag> res = new ArrayList<CNPartETag>(); | |
| 181 | + final CNListPartsResponseListener listPartsResponseHandler = new CNListPartsResponseListener() { | |
| 169 | 182 | @Override |
| 170 | - public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { | |
| 171 | - Log.w(TAG, "list parts, statusCode = " + i, throwable); | |
| 183 | + public void onFailure(int statesCode, UploadError error, Header[] responceHeaders, String response, Throwable paramThrowable) { | |
| 184 | + Log.w(TAG, "list parts, statesCode=" + statesCode, paramThrowable); | |
| 172 | 185 | } |
| 173 | 186 | |
| 174 | 187 | @Override |
| 175 | - public void onSuccess(int i, Header[] headers, CNListPartsResult cnListPartsResult) { | |
| 176 | - res.addAll(convertPart(cnListPartsResult.getCNParts())); | |
| 177 | - Log.e(TAG, "getUploadedParts = " + res.size()); | |
| 178 | - if (pause) { | |
| 179 | - doneParts = res; | |
| 180 | - pause = false; | |
| 181 | - } | |
| 182 | - if (!cnListPartsResult.isTruncated()) { | |
| 188 | + public void onSuccess(int statesCode, Header[] responceHeaders, CNListPartsResult listPartsResult) { | |
| 189 | + res.addAll(convertPart(listPartsResult.getCNParts())); | |
| 190 | + if (!listPartsResult.isTruncated()) | |
| 183 | 191 | mHandler.sendMessage(Message.obtain(mHandler, GET_UPLOADED_DONE, res)); |
| 184 | - } else { | |
| 185 | - Log.e(TAG, "File size too large. You may not use phone to upload"); | |
| 186 | - } | |
| 192 | + else | |
| 193 | + Log.e(TAG, "File size too largs. You may not use phone to upload"); | |
| 187 | 194 | } |
| 188 | 195 | }; |
| 189 | - cnUpload.listParts(key, uploadId, listener); | |
| 196 | + cnUpload.listParts(key, uploadId, listPartsResponseHandler); | |
| 190 | 197 | } |
| 191 | 198 | |
| 192 | - /** | |
| 193 | - * 获取到还没有上传的块 | |
| 194 | - * | |
| 195 | - * @param uploadedParts 已经上传的块 | |
| 196 | - * @return | |
| 197 | - */ | |
| 198 | 199 | public List<Integer> getLeftParts(List<CNPartETag> uploadedParts) { |
| 199 | - ArrayList res = new ArrayList(); | |
| 200 | + List<Integer> res = new ArrayList<Integer>(); | |
| 200 | 201 | long start = 0L; |
| 201 | 202 | int partNumber = 1; |
| 202 | - HashSet set = new HashSet(); | |
| 203 | - Iterator iterator = uploadedParts.iterator(); | |
| 204 | - | |
| 205 | - while (iterator.hasNext()) { | |
| 206 | - CNPartETag cnPartETag = (CNPartETag) iterator.next(); | |
| 207 | - set.add(Integer.valueOf(cnPartETag.getPartNumber())); | |
| 203 | + Set<Integer> set = new HashSet<Integer>(); | |
| 204 | + for (CNPartETag p : uploadedParts) { | |
| 205 | + set.add(p.getPartNumber()); | |
| 208 | 206 | } |
| 209 | - | |
| 210 | 207 | while (start < file.length()) { |
| 211 | - if (!set.contains(Integer.valueOf(partNumber))) { | |
| 212 | - res.add(Integer.valueOf(partNumber)); | |
| 213 | - } | |
| 214 | - ++partNumber; | |
| 208 | + if (!set.contains(partNumber)) | |
| 209 | + res.add(partNumber); | |
| 210 | + partNumber++; | |
| 215 | 211 | start += partSize; |
| 216 | 212 | } |
| 217 | 213 | return res; |
| 218 | 214 | } |
| 219 | 215 | |
| 220 | - /** | |
| 221 | - * 继续上传 | |
| 222 | - */ | |
| 223 | 216 | public void reUpload() { |
| 224 | - if (this.uploadId == null) { | |
| 217 | + if (uploadId == null) { | |
| 225 | 218 | Log.i(TAG, "no upload id, cannot reupload"); |
| 226 | - } else { | |
| 227 | - getUploadedParts(); | |
| 219 | + return; | |
| 228 | 220 | } |
| 221 | + getUploadedParts(); | |
| 229 | 222 | } |
| 230 | 223 | |
| 231 | - private CNPartETag cnPartETag = new CNPartETag(); | |
| 232 | - | |
| 233 | - /** | |
| 234 | - * 开始分块上传 | |
| 235 | - * | |
| 236 | - * @param startNo | |
| 237 | - * @param N | |
| 238 | - */ | |
| 239 | - public void doWithLimit(int startNo, final int N) { | |
| 240 | - | |
| 241 | - for (int i = startNo; i < startNo + concurrentNo && i < leftParts.size(); ++i) { | |
| 242 | -// Log.e(TAG, isPause() + " "); | |
| 243 | - | |
| 244 | -// if (isPause()) { | |
| 245 | -// break; | |
| 246 | -// } else { | |
| 247 | - final int partNumber = ((Integer) this.leftParts.get(i)).intValue(); | |
| 248 | - long offset = partNumber * this.partSize - partSize; | |
| 249 | - CNUploadPartRequest request = new CNUploadPartRequest(key, uploadId, file, offset, partNumber, Math.min(file.length() - offset, partSize)); | |
| 250 | - request.setCannedACL(CNCannedAccessControlList.PublicReadWrite); | |
| 251 | - request.setContentType("video/mp4"); | |
| 252 | - cnUpload.uploadPart(request, new MyUploadPartResponseHandler(key, partNumber, uploadId) { | |
| 224 | + public void reUpload(final List<CNPartETag> uploadedParts) { | |
| 225 | + final List<Integer> leftParts = getLeftParts(uploadedParts); | |
| 226 | + final int N = leftParts.size() + uploadedParts.size(); | |
| 227 | + doneParts.addAll(uploadedParts); | |
| 228 | + if (leftParts.isEmpty()) | |
| 229 | + mHandler.sendEmptyMessage(PARTS_DONE); | |
| 230 | + for (Integer partNumber : leftParts) { | |
| 231 | + long offset = partNumber * partSize - partSize; | |
| 232 | + CNUploadPartRequest uploadPartRequest = new CNUploadPartRequest(key, uploadId, file, | |
| 233 | + offset, partNumber, Math.min(file.length() - offset, partSize)); | |
| 234 | + cnUpload.uploadPart(uploadPartRequest, new MyUploadPartResponceHandler(key, partNumber, uploadId) { | |
| 253 | 235 | @Override |
| 254 | - public void onSuccess(int statusCode, Header[] responseHeaders, CNPartETag result, String key, int partNo, String uploadId) { | |
| 255 | - cnPartETag = result; | |
| 236 | + public void onSuccess(int statesCode, Header[] responceHeaders, CNPartETag result, String key, int partNo, String uploadId) { | |
| 256 | 237 | result.setPartNumber(partNo); |
| 257 | - if (!isAbortMultipartUpload) | |
| 258 | - doneParts.add(result); | |
| 259 | - cur.incrementAndGet(); | |
| 260 | - Log.e(TAG, "doneParts = " + doneParts.size() + " ,N = " + N); | |
| 261 | - if (doneParts.size() >= N) { | |
| 262 | - mHandler.sendEmptyMessage(PARATS_DONE); | |
| 263 | - } else if (cur.get() % concurrentNo == 0) { | |
| 264 | - mHandler.sendMessage(Message.obtain(mHandler, LIMIT_DONE, cur.get(), N)); | |
| 265 | - } | |
| 238 | + doneParts.add(result); | |
| 239 | + if (doneParts.size() == N) | |
| 240 | + mHandler.sendEmptyMessage(PARTS_DONE); | |
| 266 | 241 | } |
| 267 | 242 | |
| 268 | 243 | @Override |
| 269 | - public void onFailure(int statusCode, UploadError error, Header[] responseHeaders, String response, Throwable throwable, String key, int partNo, String uploadId) { | |
| 270 | - Log.w(TAG, "upload part fail, uploadId = " + uploadId + " ,key = " + key + " ,partNo = " + partNo, throwable); | |
| 271 | - if (multiListener != null) { | |
| 272 | - multiListener.onFailure(statusCode, error, responseHeaders, response, throwable); | |
| 273 | - } | |
| 244 | + public void onFailure(int statesCode, UploadError error, Header[] responceHeaders, String response, Throwable throwable, | |
| 245 | + String key, int partNo, String uploadId) { | |
| 246 | + // you may record this failure info in file, database, or backend | |
| 247 | + Log.w(TAG, "upload part fail, uploadId=" + uploadId + ",key=" + key + ",partNo=" + partNo, throwable); | |
| 274 | 248 | } |
| 275 | 249 | |
| 276 | 250 | @Override |
| 277 | - public void onTaskProcess(double progress, String key, int partNo, String uploadId) { | |
| 278 | - if (progress > 99) { | |
| 279 | - Log.d(TAG, "progress : " + progress + " ,key = " + key + " ,partNo = " + partNo); | |
| 280 | - } | |
| 251 | + public void onTaskProgress(double progress, String key, int partNo, String uploadId) { | |
| 252 | + if (progress >= 99) | |
| 253 | + Log.i(TAG, "progress:" + progress + ",key=" + key + ",partNo" + partNo); | |
| 281 | 254 | } |
| 282 | 255 | }); |
| 283 | -// } | |
| 284 | 256 | } |
| 285 | 257 | } |
| 286 | 258 | |
| 287 | - /** | |
| 288 | - * 取消分块上传 | |
| 289 | - */ | |
| 290 | - public void cancelUpload() { | |
| 291 | - CNAbortMultipartUploadRequest request = new CNAbortMultipartUploadRequest(key, uploadId); | |
| 292 | - cnUpload.abortMultipartUpload(request, new CNAbortMultipartUploadResponseListener() { | |
| 293 | - @Override | |
| 294 | - public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { | |
| 295 | - Log.e(TAG, "abortMultipart fail , stateCode = " + i, throwable); | |
| 296 | - } | |
| 297 | - | |
| 298 | - @Override | |
| 299 | - public void onSuccess(int i, Header[] headers) { | |
| 300 | - Log.e(TAG, "abortMultipart success"); | |
| 301 | - isAbortMultipartUpload = true; | |
| 302 | - if (uploadId != null) { | |
| 303 | - uploadId = null; | |
| 304 | - } | |
| 305 | - if (doneParts != null) doneParts.clear(); | |
| 306 | - } | |
| 307 | - }); | |
| 308 | - } | |
| 309 | - | |
| 310 | - public void reUpload(List<CNPartETag> uploadedParts) { | |
| 311 | - leftParts = getLeftParts(uploadedParts); | |
| 312 | - Log.e(TAG, "reupload uploadedParts = " + uploadedParts.size() + " , leftParts = " + leftParts.size()); | |
| 313 | - | |
| 314 | - int N = leftParts.size() + uploadedParts.size(); | |
| 315 | - cur = new AtomicInteger(0); | |
| 316 | - | |
| 317 | -// doneParts.addAll(uploadedParts); | |
| 318 | - | |
| 319 | - if (leftParts.isEmpty()) { | |
| 320 | - mHandler.sendEmptyMessage(PARATS_DONE); | |
| 321 | - } | |
| 322 | - Log.e(TAG, "reupload uploadedsize = " + doneParts.size() + " ,N = " + N); | |
| 323 | - doWithLimit(0, N); | |
| 324 | - } | |
| 325 | - | |
| 326 | 259 | private void uploadParts() { |
| 327 | 260 | reUpload(new ArrayList<CNPartETag>()); |
| 328 | 261 | } |
| 329 | 262 | |
| 330 | - /** | |
| 331 | - * 组装上传的块 | |
| 332 | - */ | |
| 333 | 263 | private void completeUpload() { |
| 334 | - if (multiListener == null) { | |
| 335 | - multiListener = new CNCompleteMultipartUploadResponseListener() { | |
| 336 | - @Override | |
| 337 | - public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { | |
| 338 | - Log.w(TAG, "complete upload fail, statusCode = " + i, throwable); | |
| 339 | - } | |
| 340 | - | |
| 341 | - @Override | |
| 342 | - public void onSuccess(int i, Header[] headers, CNCompleteMultipartUploadResult completeMultipartUploadResult) { | |
| 343 | - Log.i(TAG, "complete upload, key = " + key + ", bucketName = " + bucketName + " , uploadId = " + uploadId + "\n" + completeMultipartUploadResult.toString()); | |
| 344 | - | |
| 345 | - } | |
| 346 | - }; | |
| 347 | - } | |
| 348 | - CNCompleteMultipartUploadRequest request = new CNCompleteMultipartUploadRequest(bucketName, key); | |
| 349 | - request.setContentType("video/mp4"); | |
| 350 | - request.setCNPartETags(doneParts); | |
| 351 | - request.setUploadId(uploadId); | |
| 352 | - cnUpload.completeMultipartUpload(request, multiListener); | |
| 353 | - } | |
| 354 | - | |
| 355 | - class MyHandler extends Handler { | |
| 356 | - MyHandler() { | |
| 357 | - | |
| 358 | - } | |
| 359 | - | |
| 360 | - @Override | |
| 361 | - public void handleMessage(Message msg) { | |
| 362 | - switch (msg.what) { | |
| 363 | - case INIT_DONE: | |
| 364 | - uploadParts(); | |
| 365 | - break; | |
| 366 | - case PARATS_DONE: | |
| 367 | - completeUpload(); | |
| 368 | - break; | |
| 369 | - case COMPLETE_DONE: | |
| 370 | - default: | |
| 371 | - break; | |
| 372 | - case GET_UPLOADED_DONE: | |
| 373 | - List res = (List) msg.obj; | |
| 374 | - reUpload(res); | |
| 375 | - break; | |
| 376 | - case LIMIT_DONE: | |
| 377 | - int no = msg.arg1; | |
| 378 | - int N = msg.arg2; | |
| 379 | - doWithLimit(no, N); | |
| 380 | - break; | |
| 264 | + cnUpload.completeMultipartUpload(key, uploadId, doneParts, new CNCompleteMultipartUploadResponseListener() { | |
| 265 | + @Override | |
| 266 | + public void onFailure(int statesCode, UploadError error, Header[] responceHeaders, String response, Throwable paramThrowable) { | |
| 267 | + Log.w(TAG, "complete upload fail, statusCode=" + statesCode, paramThrowable); | |
| 381 | 268 | } |
| 382 | - } | |
| 383 | - } | |
| 384 | - | |
| 385 | - abstract class MyUploadPartResponseHandler implements CNUploadPartResponseListener { | |
| 386 | - private String key; | |
| 387 | - private int partNo; | |
| 388 | - private String uploadId; | |
| 389 | - | |
| 390 | - public abstract void onSuccess(int statusCode, Header[] responseHeaders, CNPartETag result, String key, int partNo, String uploadId); | |
| 391 | - | |
| 392 | - public abstract void onFailure(int statusCode, UploadError error, Header[] responseHeaders, String response, Throwable throwable, String key, int partNo, String uploadId); | |
| 393 | - | |
| 394 | - public abstract void onTaskProcess(double progress, String key, int partNo, String uploadId); | |
| 395 | 269 | |
| 396 | - public MyUploadPartResponseHandler(String key, int partNo, String uploadId) { | |
| 397 | - this.key = key; | |
| 398 | - this.partNo = partNo; | |
| 399 | - this.uploadId = uploadId; | |
| 400 | - } | |
| 401 | - | |
| 402 | - @Override | |
| 403 | - public void onTaskProgress(double v) { | |
| 404 | - this.onTaskProcess(v, this.key, this.partNo, this.uploadId); | |
| 405 | - } | |
| 406 | - | |
| 407 | - @Override | |
| 408 | - public void onSuccess(int i, Header[] headers, CNPartETag cnPartETag) { | |
| 409 | - this.onSuccess(i, headers, cnPartETag, this.key, this.partNo, this.uploadId); | |
| 410 | - } | |
| 411 | - | |
| 412 | - @Override | |
| 413 | - public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { | |
| 414 | - this.onFailure(i, uploadError, headers, s, throwable, this.key, this.partNo, this.uploadId); | |
| 415 | - } | |
| 270 | + @Override | |
| 271 | + public void onSuccess(int statesCode, Header[] responceHeaders, CNCompleteMultipartUploadResult result) { | |
| 272 | + Log.i(TAG, "complete upload, key=" + key); | |
| 273 | + } | |
| 274 | + }); | |
| 416 | 275 | } |
| 417 | 276 | |
| 418 | -// public boolean isPause() { | |
| 419 | -// return pause; | |
| 420 | -// } | |
| 421 | - | |
| 422 | -// public void setPause(boolean pause) { | |
| 423 | -// this.pause = pause; | |
| 424 | -// } | |
| 425 | - | |
| 426 | 277 | /** |
| 427 | 278 | * 此暂停方法,会立即暂停,继续上传时,当前块重新上传 |
| 428 | 279 | * 也可以通过不上传下一块的方法暂停上传 |
| ... | ... | @@ -431,6 +282,5 @@ public class MultiUploader { |
| 431 | 282 | */ |
| 432 | 283 | public void pause(Context context) { |
| 433 | 284 | cnUpload.pause(context); |
| 434 | - pause = true; | |
| 435 | 285 | } |
| 436 | 286 | } | ... | ... |
app/src/main/java/com/cnlive/cnUploadDemo/activity/UploadActivity.java
| ... | ... | @@ -97,6 +97,11 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 97 | 97 | switchDir(Environment.getExternalStorageDirectory()); |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | + /** | |
| 101 | + * 选择文件 | |
| 102 | + * | |
| 103 | + * @param dir 文件 | |
| 104 | + */ | |
| 100 | 105 | private void switchDir(File dir) { |
| 101 | 106 | if (dir == null || !dir.exists() || dir.isFile()) |
| 102 | 107 | throw new IllegalArgumentException("illegal dir"); |
| ... | ... | @@ -152,8 +157,11 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 152 | 157 | return super.onKeyDown(keyCode, event); |
| 153 | 158 | } |
| 154 | 159 | |
| 160 | + | |
| 155 | 161 | /** |
| 156 | 162 | * 上传操作,如果大于16MB,则使用分块上传 |
| 163 | + * | |
| 164 | + * @param item 自定义文件对象 | |
| 157 | 165 | */ |
| 158 | 166 | private void doUpload(final UploadFile item) { |
| 159 | 167 | if (item.file == null) { |
| ... | ... | @@ -178,7 +186,7 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 178 | 186 | /** |
| 179 | 187 | * 单块上传 |
| 180 | 188 | * |
| 181 | - * @param item | |
| 189 | + * @param item 自定义文件对象 | |
| 182 | 190 | */ |
| 183 | 191 | private void doSingleUpload(final UploadFile item) { |
| 184 | 192 | |
| ... | ... | @@ -189,9 +197,16 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 189 | 197 | //设置上传的文件的内容类型 |
| 190 | 198 | request.setContentType("video/mp4"); |
| 191 | 199 | cnUpload.putObject(request, new CNPutObjectResponseListener() { |
| 200 | + /** | |
| 201 | + * 上传失败 | |
| 202 | + * @param i Http请求返回的状态码,200表示请求成功,400表示客户端请求错误,403表示签名错误或本地日期时间错误 | |
| 203 | + * @param uploadError 失败时返回的实体类,包含errorCode、errorMessage、serverError | |
| 204 | + * @param headers Http请求响应报头 | |
| 205 | + * @param s 失败时返回的响应正文 | |
| 206 | + * @param throwable 出错时抛出的异常 | |
| 207 | + */ | |
| 192 | 208 | @Override |
| 193 | 209 | public void onTaskFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { |
| 194 | - //失败 | |
| 195 | 210 | Log.d(TAG, uploadError.getErrorMessage() + " : " + s + " : " + i); |
| 196 | 211 | List<UploadFile> uploadFiles = dataSource.get(currentDir |
| 197 | 212 | .getPath()); |
| ... | ... | @@ -205,16 +220,22 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 205 | 220 | myHandler.sendEmptyMessage(UPDATE_SINGLE_UPLOAD_STATUS); |
| 206 | 221 | } |
| 207 | 222 | |
| 223 | + /** | |
| 224 | + * 上传成功 | |
| 225 | + * @param i Http请求返回的状态码 | |
| 226 | + * @param headers Http请求响应报头 | |
| 227 | + */ | |
| 208 | 228 | @Override |
| 209 | 229 | public void onTaskSuccess(int i, Header[] headers) { |
| 210 | - //上传成功 | |
| 211 | 230 | Log.i(TAG, "single upload success"); |
| 212 | 231 | getUploadedUrl(); |
| 213 | 232 | } |
| 214 | 233 | |
| 234 | + /** | |
| 235 | + * 上传开始 | |
| 236 | + */ | |
| 215 | 237 | @Override |
| 216 | 238 | public void onTaskStart() { |
| 217 | - //上传开始 | |
| 218 | 239 | List<UploadFile> uploadFiles = dataSource.get(currentDir |
| 219 | 240 | .getPath()); |
| 220 | 241 | for (UploadFile file : uploadFiles) { |
| ... | ... | @@ -229,9 +250,11 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 229 | 250 | myHandler.sendEmptyMessage(UPDATE_SINGLE_UPLOAD_STATUS); |
| 230 | 251 | } |
| 231 | 252 | |
| 253 | + /** | |
| 254 | + * 上传结束 包括上传成功结束与上传失败结束 | |
| 255 | + */ | |
| 232 | 256 | @Override |
| 233 | 257 | public void onTaskFinish() { |
| 234 | - //上传结束 包括上传成功结束与上传失败结束 | |
| 235 | 258 | List<UploadFile> uploadFiles = dataSource.get(currentDir |
| 236 | 259 | .getPath()); |
| 237 | 260 | for (UploadFile file : uploadFiles) { |
| ... | ... | @@ -246,15 +269,20 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 246 | 269 | myHandler.sendEmptyMessage(UPDATE_SINGLE_UPLOAD_STATUS); |
| 247 | 270 | } |
| 248 | 271 | |
| 272 | + /** | |
| 273 | + * 上传取消 | |
| 274 | + */ | |
| 249 | 275 | @Override |
| 250 | 276 | public void onTaskCancel() { |
| 251 | - //上传取消 | |
| 252 | 277 | Log.d(TAG, "single upload cancel"); |
| 253 | 278 | } |
| 254 | 279 | |
| 280 | + /** | |
| 281 | + * 上传进度 | |
| 282 | + * @param v 返回上传进度 | |
| 283 | + */ | |
| 255 | 284 | @Override |
| 256 | 285 | public void onTaskProgress(double v) { |
| 257 | - //上传进度 | |
| 258 | 286 | List<UploadFile> uploadFiles = dataSource.get(currentDir.getPath()); |
| 259 | 287 | for (UploadFile file : uploadFiles) { |
| 260 | 288 | if (file.file.getPath().equalsIgnoreCase(item.file.getPath())) { |
| ... | ... | @@ -272,7 +300,7 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 272 | 300 | /** |
| 273 | 301 | * 初始化分块上传 |
| 274 | 302 | * |
| 275 | - * @param item | |
| 303 | + * @param item 自定义文件对象 | |
| 276 | 304 | */ |
| 277 | 305 | private void doMultipartUpload(final UploadFile item) { |
| 278 | 306 | |
| ... | ... | @@ -283,6 +311,14 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 283 | 311 | //设置bucket权限 |
| 284 | 312 | request.setCannedACL(CNCannedAccessControlList.PublicRead); |
| 285 | 313 | cnUpload.initiateMultipartUpload(request, new CNInitiateMultipartUploadResponseListener() { |
| 314 | + /** | |
| 315 | + * | |
| 316 | + * @param i Http请求返回的状态码,200表示请求成功,400表示客户端请求错误,403表示签名错误或本地日期时间错误 | |
| 317 | + * @param uploadError 失败时返回的实体类,包含errorCode、errorMessage、serverError | |
| 318 | + * @param headers Http请求响应报头 | |
| 319 | + * @param s 失败时返回的响应正文 | |
| 320 | + * @param throwable 出错时抛出的异常 | |
| 321 | + */ | |
| 286 | 322 | @Override |
| 287 | 323 | public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { |
| 288 | 324 | //初始化多块上传失败 |
| ... | ... | @@ -298,6 +334,12 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 298 | 334 | myHandler.sendEmptyMessage(UPDATE_SINGLE_UPLOAD_STATUS); |
| 299 | 335 | } |
| 300 | 336 | |
| 337 | + /** | |
| 338 | + * 初始化多块上传成功 | |
| 339 | + * @param i Http请求返回的状态码 | |
| 340 | + * @param headers Http请求响应报头 | |
| 341 | + * @param cnInitiateMultipartUploadResult 初始化分块上传结果实体类,包含bucketName、objectKey、uploadId(分块上传的文件的标识)信息等 | |
| 342 | + */ | |
| 301 | 343 | @Override |
| 302 | 344 | public void onSuccess(int i, Header[] headers, CNInitiateMultipartUploadResult cnInitiateMultipartUploadResult) { |
| 303 | 345 | //初始化多块上传成功 |
| ... | ... | @@ -319,6 +361,12 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 319 | 361 | |
| 320 | 362 | UploadPartRequestFactory localUploadPartRequestFactory; |
| 321 | 363 | |
| 364 | + /** | |
| 365 | + * 上传分块 | |
| 366 | + * | |
| 367 | + * @param initResult 初始化分块上传后获得的result,包含bucketName、objectKey、uploadId | |
| 368 | + * @param item 自定义文件对象 | |
| 369 | + */ | |
| 322 | 370 | private void beginMultiUpload(CNInitiateMultipartUploadResult initResult, |
| 323 | 371 | UploadFile item) { |
| 324 | 372 | localUploadPartRequestFactory = new UploadPartRequestFactory( |
| ... | ... | @@ -336,8 +384,8 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 336 | 384 | /** |
| 337 | 385 | * 上传分块 |
| 338 | 386 | * |
| 339 | - * @param requestFactory | |
| 340 | - * @param item | |
| 387 | + * @param requestFactory UploadPartRequest工厂,用于分块上传操作 | |
| 388 | + * @param item 自定义文件对象 | |
| 341 | 389 | */ |
| 342 | 390 | private void uploadpart(final UploadPartRequestFactory requestFactory, final UploadFile item) { |
| 343 | 391 | if (requestFactory.hasMoreRequests()) { |
| ... | ... | @@ -345,6 +393,12 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 345 | 393 | cnUpload.uploadPart(request, new CNUploadPartResponseListener() { |
| 346 | 394 | double progressInFile = 0; |
| 347 | 395 | |
| 396 | + /** | |
| 397 | + * 上传分块成功 | |
| 398 | + * @param i Http请求返回的状态码 | |
| 399 | + * @param headers Http请求响应报头 | |
| 400 | + * @param cnPartETag | |
| 401 | + */ | |
| 348 | 402 | @Override |
| 349 | 403 | public void onSuccess(int i, Header[] headers, CNPartETag cnPartETag) { |
| 350 | 404 | //上传分块成功 |
| ... | ... | @@ -357,6 +411,14 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 357 | 411 | myHandler.sendMessage(message); |
| 358 | 412 | } |
| 359 | 413 | |
| 414 | + /** | |
| 415 | + * 上传分块失败 | |
| 416 | + * @param i Http请求返回的状态码,200表示请求成功,400表示客户端请求错误,403表示签名错误或本地日期时间错误 | |
| 417 | + * @param uploadError 失败时返回的实体类,包含errorCode、errorMessage、serverError | |
| 418 | + * @param headers Http请求响应报头 | |
| 419 | + * @param s 失败时返回的响应正文 | |
| 420 | + * @param throwable 出错时抛出的异常 | |
| 421 | + */ | |
| 360 | 422 | @Override |
| 361 | 423 | public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { |
| 362 | 424 | //上传分块失败 |
| ... | ... | @@ -374,6 +436,10 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 374 | 436 | myHandler.sendEmptyMessage(UPDATE_SINGLE_UPLOAD_STATUS); |
| 375 | 437 | } |
| 376 | 438 | |
| 439 | + /** | |
| 440 | + * 上传分块的进度 | |
| 441 | + * @param v 上传分块的进度 | |
| 442 | + */ | |
| 377 | 443 | @Override |
| 378 | 444 | public void onTaskProgress(double v) { |
| 379 | 445 | //上传分块进度 |
| ... | ... | @@ -415,14 +481,22 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 415 | 481 | /** |
| 416 | 482 | * 罗列出已经上传的块 |
| 417 | 483 | * |
| 418 | - * @param request | |
| 419 | - * @param item | |
| 484 | + * @param request 请求封装类,应包含uploadId, | |
| 485 | + * 上传的文件及其指定offset和size信息 | |
| 486 | + * @param item 自定义文件对象 | |
| 420 | 487 | */ |
| 421 | 488 | private void listParts(CNListPartsRequest request, final UploadFile item) { |
| 422 | 489 | cnUpload.listParts(request, new CNListPartsResponseListener() { |
| 490 | + /** | |
| 491 | + * 罗列已经上传的分块失败 | |
| 492 | + * @param i Http请求返回的状态码,200表示请求成功,400表示客户端请求错误,403表示签名错误或本地日期时间错误 | |
| 493 | + * @param uploadError 失败时返回的实体类,包含errorCode、errorMessage、serverError | |
| 494 | + * @param headers Http请求响应报头 | |
| 495 | + * @param s 失败时返回的响应正文 | |
| 496 | + * @param throwable 出错时抛出的异常 | |
| 497 | + */ | |
| 423 | 498 | @Override |
| 424 | 499 | public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { |
| 425 | - //罗列已经上传的分块失败 | |
| 426 | 500 | List<UploadFile> uploadFiles = dataSource.get(currentDir |
| 427 | 501 | .getPath()); |
| 428 | 502 | for (UploadFile file : uploadFiles) { |
| ... | ... | @@ -435,9 +509,14 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 435 | 509 | myHandler.sendEmptyMessage(UPDATE_SINGLE_UPLOAD_STATUS); |
| 436 | 510 | } |
| 437 | 511 | |
| 512 | + /** | |
| 513 | + *罗列已经上传的分块成功 | |
| 514 | + * @param i Http请求返回的状态码 | |
| 515 | + * @param headers Http请求响应报头 | |
| 516 | + * @param cnListPartsResult 成功时返回CNListPartsResult结果实体类,包含CNOwner及一个Parts容器类 | |
| 517 | + */ | |
| 438 | 518 | @Override |
| 439 | 519 | public void onSuccess(int i, Header[] headers, CNListPartsResult cnListPartsResult) { |
| 440 | - //罗列已经上传的分块成功 | |
| 441 | 520 | Message message = myHandler.obtainMessage(); |
| 442 | 521 | message.what = LIST_PART_FINISH; |
| 443 | 522 | message.obj = cnListPartsResult; |
| ... | ... | @@ -452,11 +531,20 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 452 | 531 | /** |
| 453 | 532 | * 完成分块上传,组装上传的分块 |
| 454 | 533 | * |
| 455 | - * @param request | |
| 456 | - * @param item | |
| 534 | + * @param request 请求封装类,应包含uploadId, | |
| 535 | + * 上传的文件及其指定offset和size信息 | |
| 536 | + * @param item 自定义文件对象 | |
| 457 | 537 | */ |
| 458 | 538 | private void completeUploadPart(CNCompleteMultipartUploadRequest request, final UploadFile item) { |
| 459 | 539 | cnUpload.completeMultipartUpload(request, new CNCompleteMultipartUploadResponseListener() { |
| 540 | + /** | |
| 541 | + * 组装上传的分块失败 | |
| 542 | + * @param i Http请求返回的状态码,200表示请求成功,400表示客户端请求错误,403表示签名错误或本地日期时间错误 | |
| 543 | + * @param uploadError 失败时返回的实体类,包含errorCode、errorMessage、serverError | |
| 544 | + * @param headers Http请求响应报头 | |
| 545 | + * @param s 失败时返回的响应正文 | |
| 546 | + * @param throwable 出错时抛出的异常 | |
| 547 | + */ | |
| 460 | 548 | @Override |
| 461 | 549 | public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { |
| 462 | 550 | List<UploadFile> uploadFiles = dataSource |
| ... | ... | @@ -473,6 +561,13 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 473 | 561 | myHandler.sendEmptyMessage(0); |
| 474 | 562 | } |
| 475 | 563 | |
| 564 | + /** | |
| 565 | + * | |
| 566 | + * @param i Http请求返回的状态码 | |
| 567 | + * @param headers Http请求响应报头 | |
| 568 | + * @param cnCompleteMultipartUploadResult 成功时返回结果实体类,包含上传的文件的基本信息(objectKey、uploadId等) | |
| 569 | + | |
| 570 | + */ | |
| 476 | 571 | @Override |
| 477 | 572 | public void onSuccess(int i, Header[] headers, CNCompleteMultipartUploadResult cnCompleteMultipartUploadResult) { |
| 478 | 573 | List<UploadFile> uploadFiles = dataSource |
| ... | ... | @@ -493,15 +588,29 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 493 | 588 | |
| 494 | 589 | /** |
| 495 | 590 | * 取消分块上传 |
| 591 | + * 取消后下一次需要重新上传 | |
| 496 | 592 | */ |
| 497 | 593 | private void abortMultiUpload() { |
| 498 | 594 | CNAbortMultipartUploadRequest request = new CNAbortMultipartUploadRequest(localUploadPartRequestFactory.getObjectKey(), localUploadPartRequestFactory.getUploadId()); |
| 499 | 595 | cnUpload.abortMultipartUpload(request, new CNAbortMultipartUploadResponseListener() { |
| 596 | + /** | |
| 597 | + * 取消分块上传失败 | |
| 598 | + * @param i Http请求返回的状态码,200表示请求成功,400表示客户端请求错误,403表示签名错误或本地日期时间错误 | |
| 599 | + * @param uploadError 失败时返回的实体类,包含errorCode、errorMessage、serverError | |
| 600 | + * @param headers Http请求响应报头 | |
| 601 | + * @param s 失败时返回的响应正文 | |
| 602 | + * @param throwable 出错时抛出的异常 | |
| 603 | + */ | |
| 500 | 604 | @Override |
| 501 | 605 | public void onFailure(int i, UploadError uploadError, Header[] headers, String s, Throwable throwable) { |
| 502 | 606 | Toast.makeText(UploadActivity.this, "取消分块上传失败", Toast.LENGTH_SHORT).show(); |
| 503 | 607 | } |
| 504 | 608 | |
| 609 | + /** | |
| 610 | + * 取消分块上传成功 | |
| 611 | + * @param i Http请求返回的状态码 | |
| 612 | + * @param headers Http请求响应报头 | |
| 613 | + */ | |
| 505 | 614 | @Override |
| 506 | 615 | public void onSuccess(int i, Header[] headers) { |
| 507 | 616 | Toast.makeText(UploadActivity.this, "取消分块上传成功", Toast.LENGTH_SHORT).show(); |
| ... | ... | @@ -532,6 +641,7 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 532 | 641 | requestFactory = (UploadPartRequestFactory) bundle |
| 533 | 642 | .get("requestFactory"); |
| 534 | 643 | item = (UploadFile) bundle.get("uploadFile"); |
| 644 | + //上传分块 | |
| 535 | 645 | uploadpart(requestFactory, item); |
| 536 | 646 | break; |
| 537 | 647 | case UPLOAD_PART_FINISH: |
| ... | ... | @@ -540,8 +650,10 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 540 | 650 | .get("requestFactory"); |
| 541 | 651 | item = (UploadFile) bundle.get("uploadFile"); |
| 542 | 652 | CNListPartsRequest listRequest = new CNListPartsRequest( |
| 543 | - requestFactory.getObjectKey(), | |
| 544 | - requestFactory.getUploadId()); | |
| 653 | + requestFactory.getObjectKey(),//指定的object键 | |
| 654 | + requestFactory.getUploadId() //初始化多块上传得到的uploadId | |
| 655 | + ); | |
| 656 | + //罗列已上传的块 | |
| 545 | 657 | listParts(listRequest, item); |
| 546 | 658 | break; |
| 547 | 659 | case LIST_PART_FINISH: |
| ... | ... | @@ -550,6 +662,7 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 550 | 662 | item = (UploadFile) bundle.get("uploadFile"); |
| 551 | 663 | CNCompleteMultipartUploadRequest comRequest = new CNCompleteMultipartUploadRequest( |
| 552 | 664 | listResult); |
| 665 | + //组装分块 | |
| 553 | 666 | completeUploadPart(comRequest, item); |
| 554 | 667 | break; |
| 555 | 668 | default: |
| ... | ... | @@ -571,7 +684,7 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 571 | 684 | cnUpload.getUploadedUrlInfo(objectKey, FileType.COMMON_FILE, new OnUploadedUrlInfoListener() { |
| 572 | 685 | /** |
| 573 | 686 | * 返回资源路径 |
| 574 | - * @param s | |
| 687 | + * @param s 资源路径 | |
| 575 | 688 | */ |
| 576 | 689 | @Override |
| 577 | 690 | public void onSuccess(String s) { |
| ... | ... | @@ -580,8 +693,8 @@ public class UploadActivity extends Activity implements AdapterView.OnItemClickL |
| 580 | 693 | |
| 581 | 694 | /** |
| 582 | 695 | * 返回错误信息 |
| 583 | - * @param s | |
| 584 | - * @param s1 | |
| 696 | + * @param s 返回errorCode | |
| 697 | + * @param s1 返回errorMessage | |
| 585 | 698 | */ |
| 586 | 699 | @Override |
| 587 | 700 | public void onError(String s, String s1) { | ... | ... |
app/src/main/java/com/cnlive/cnUploadDemo/model/UploadFile.java
| ... | ... | @@ -7,26 +7,95 @@ import java.io.Serializable; |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | 9 | * Created by Lynn on 2017/8/10. |
| 10 | + * 自定义文件对象 | |
| 10 | 11 | */ |
| 11 | 12 | |
| 12 | 13 | public class UploadFile implements Serializable { |
| 13 | 14 | public static final long serialVersionUID = 1L; |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 文件上传未开始 | |
| 18 | + */ | |
| 14 | 19 | public static final int STATUS_NOT_START = 0; |
| 20 | + | |
| 21 | + /** | |
| 22 | + * 准备上传 | |
| 23 | + */ | |
| 15 | 24 | public static final int STATUS_STARTED = 1; |
| 25 | + | |
| 26 | + /** | |
| 27 | + * 上传中 | |
| 28 | + */ | |
| 16 | 29 | public static final int STATUS_UPLOADING = 2; |
| 30 | + | |
| 31 | + /** | |
| 32 | + * 初始化完成 | |
| 33 | + */ | |
| 17 | 34 | public static final int STATUS_INIT = 3; |
| 35 | + | |
| 36 | + /** | |
| 37 | + * 分块上传 | |
| 38 | + */ | |
| 18 | 39 | public static final int STATUS_UPLOADPART = 4; |
| 40 | + | |
| 41 | + /** | |
| 42 | + * 获取上传的快 | |
| 43 | + */ | |
| 19 | 44 | public static final int STATUS_LISTING = 5; |
| 45 | + | |
| 46 | + /** | |
| 47 | + * 合并完成 | |
| 48 | + */ | |
| 20 | 49 | public static final int STATUS_COMPLETE = 6; |
| 50 | + | |
| 51 | + /** | |
| 52 | + * 完成上传 | |
| 53 | + */ | |
| 21 | 54 | public static final int STATUS_FINISH = 7; |
| 55 | + | |
| 56 | + /** | |
| 57 | + * 上传失败 | |
| 58 | + */ | |
| 22 | 59 | public static final int STATUS_FAIL = 8; |
| 60 | + | |
| 61 | + /** | |
| 62 | + * 上传失败 | |
| 63 | + */ | |
| 23 | 64 | public static final int STATUS_INIT_FAIL = 9; |
| 65 | + | |
| 66 | + /** | |
| 67 | + * 分块上传失败 | |
| 68 | + */ | |
| 24 | 69 | public static final int STATUS_UPLOADPART_FAIL = 10; |
| 70 | + | |
| 71 | + /** | |
| 72 | + * 获取块失败 | |
| 73 | + */ | |
| 25 | 74 | public static final int STATUS_LISTING_FAIL = 11; |
| 75 | + | |
| 76 | + /** | |
| 77 | + * 文件合并失败 | |
| 78 | + */ | |
| 26 | 79 | public static final int STATUS_COMPLETE_FAIL = 12; |
| 80 | + | |
| 81 | + /** | |
| 82 | + * 文件icon | |
| 83 | + */ | |
| 27 | 84 | public Drawable icon; |
| 85 | + | |
| 86 | + /** | |
| 87 | + * 文件 | |
| 88 | + */ | |
| 28 | 89 | public File file; |
| 90 | + | |
| 91 | + /** | |
| 92 | + * 上传进度 | |
| 93 | + */ | |
| 29 | 94 | public int progress; |
| 95 | + | |
| 96 | + /** | |
| 97 | + * 上传状态 | |
| 98 | + */ | |
| 30 | 99 | public int status; |
| 31 | 100 | |
| 32 | 101 | @Override | ... | ... |
app/src/main/java/com/cnlive/cnUploadDemo/utils/UploadPartRequestFactory.java
| ... | ... | @@ -6,62 +6,94 @@ import java.io.File; |
| 6 | 6 | import java.io.Serializable; |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | - * | |
| 10 | 9 | * UploadPartRequest工厂,用于分块上传操作 |
| 11 | - * | |
| 12 | 10 | */ |
| 13 | -public class UploadPartRequestFactory implements Serializable{ | |
| 14 | - private static final long serialVersionUID = 1L; | |
| 15 | - private String key; | |
| 16 | - private String uploadId; | |
| 17 | - private File file; | |
| 18 | - public int partNumber = 1; | |
| 19 | - private long offset = 0L; | |
| 20 | - private long remainingBytes; | |
| 21 | - public long partSize ; | |
| 22 | - private long uploadedSize; | |
| 23 | - | |
| 24 | - public UploadPartRequestFactory(String objectKey , String uploadId , File file , long partSize ) { | |
| 25 | - this.uploadId = uploadId; | |
| 26 | - this.key = objectKey; | |
| 27 | - this.file = file; | |
| 28 | - this.remainingBytes = file.length(); | |
| 29 | - this.partSize = partSize; | |
| 30 | - this.partNumber = 1; | |
| 31 | - this.uploadedSize = 0; | |
| 32 | - } | |
| 33 | - | |
| 34 | - public synchronized boolean hasMoreRequests() { | |
| 35 | - return this.remainingBytes > 0L; | |
| 36 | - } | |
| 37 | - | |
| 38 | - // 计算下一个UploadPartRequest配置参数,并返回对象 | |
| 39 | - public synchronized CNUploadPartRequest getNextUploadPartRequest() { | |
| 40 | - boolean bool = this.remainingBytes - this.partSize <= 0L; | |
| 41 | - CNUploadPartRequest localUploadPartRequest = null; | |
| 42 | - uploadedSize = file.length() - this.remainingBytes ; | |
| 43 | - localUploadPartRequest = new CNUploadPartRequest( key,uploadId, file, offset, partNumber++, partSize); | |
| 44 | - this.offset += partSize; | |
| 45 | - this.remainingBytes -= partSize; | |
| 46 | - localUploadPartRequest.setLastPart(bool); | |
| 47 | - return localUploadPartRequest; | |
| 48 | - } | |
| 49 | - | |
| 50 | - | |
| 51 | - public synchronized long getUploadedSize (){ | |
| 52 | - return this.uploadedSize; | |
| 53 | - } | |
| 54 | - | |
| 55 | - public synchronized File getFile(){ | |
| 56 | - return this.file; | |
| 57 | - } | |
| 58 | - | |
| 59 | - public synchronized String getUploadId(){ | |
| 60 | - return this.uploadId; | |
| 61 | - } | |
| 62 | - | |
| 63 | - public synchronized String getObjectKey() { | |
| 64 | - return this.key; | |
| 65 | - } | |
| 66 | - | |
| 11 | +public class UploadPartRequestFactory implements Serializable { | |
| 12 | + | |
| 13 | + private static final long serialVersionUID = 1L; | |
| 14 | + /** | |
| 15 | + * 指定的Object键 | |
| 16 | + */ | |
| 17 | + private String key; | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * 初始化时得到的uploadId | |
| 21 | + */ | |
| 22 | + private String uploadId; | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 需要上传的file | |
| 26 | + */ | |
| 27 | + private File file; | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * 此分块是第几块 | |
| 31 | + */ | |
| 32 | + public int partNumber = 1; | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 此分块在文件中内容的起始位置 | |
| 36 | + */ | |
| 37 | + private long offset = 0L; | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * 剩余大小 | |
| 41 | + */ | |
| 42 | + private long remainingBytes; | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * 此分块的大小,单位为Byte | |
| 46 | + */ | |
| 47 | + public long partSize; | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * 已经上传大小 | |
| 51 | + */ | |
| 52 | + private long uploadedSize; | |
| 53 | + | |
| 54 | + public UploadPartRequestFactory(String objectKey, String uploadId, File file, long partSize) { | |
| 55 | + this.uploadId = uploadId; | |
| 56 | + this.key = objectKey; | |
| 57 | + this.file = file; | |
| 58 | + this.remainingBytes = file.length(); | |
| 59 | + this.partSize = partSize; | |
| 60 | + this.partNumber = 1; | |
| 61 | + this.uploadedSize = 0; | |
| 62 | + } | |
| 63 | + | |
| 64 | + public synchronized boolean hasMoreRequests() { | |
| 65 | + return this.remainingBytes > 0L; | |
| 66 | + } | |
| 67 | + | |
| 68 | + // 计算下一个UploadPartRequest配置参数,并返回对象 | |
| 69 | + public synchronized CNUploadPartRequest getNextUploadPartRequest() { | |
| 70 | + boolean bool = this.remainingBytes - this.partSize <= 0L; | |
| 71 | + CNUploadPartRequest localUploadPartRequest = null; | |
| 72 | + uploadedSize = file.length() - this.remainingBytes; | |
| 73 | + | |
| 74 | + localUploadPartRequest = new CNUploadPartRequest(key, uploadId, file, offset, partNumber++, partSize); | |
| 75 | + | |
| 76 | + this.offset += partSize; | |
| 77 | + this.remainingBytes -= partSize; | |
| 78 | + localUploadPartRequest.setLastPart(bool); | |
| 79 | + return localUploadPartRequest; | |
| 80 | + } | |
| 81 | + | |
| 82 | + | |
| 83 | + public synchronized long getUploadedSize() { | |
| 84 | + return this.uploadedSize; | |
| 85 | + } | |
| 86 | + | |
| 87 | + public synchronized File getFile() { | |
| 88 | + return this.file; | |
| 89 | + } | |
| 90 | + | |
| 91 | + public synchronized String getUploadId() { | |
| 92 | + return this.uploadId; | |
| 93 | + } | |
| 94 | + | |
| 95 | + public synchronized String getObjectKey() { | |
| 96 | + return this.key; | |
| 97 | + } | |
| 98 | + | |
| 67 | 99 | } | ... | ... |