Commit f41a44c3f69d4af0998976eadd1271e6de29b375

Authored by 王琳
1 parent 76084802

添加注释

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 }
... ...