Android阿里云OSS多文件同步上传和删除方案

上个项目中使用的是阿里云OSS,查阅了官方文档,发现居然没有多文件上传相关说明文档,只有一个单文件异步上传的说明。既没有多文件上传,又没有同步上传,删除文件亦然,凌乱。想到之前做过的七牛云开发,决定用java递归的方式实现多文件同步上传和删除,递归有风险,使用需谨慎哈。

阿里云的配置和初始化官方已经说的很明白了,那么这里就直接了当说关键的:

一般来说我们都是获得多文件对应的本地地址List集合,然后递归每个url进行上传 ---->

    /**
     * 上传多文件
     * 
     * @param urls
     */
    public void uploadFiles(List<String> urls) {
        if (null == urls || urls.size() == 0) {
            return;
        } // 上传文件
        ossUpload(urls);
    }

下面是阿里云上传递归体----->

    /**
     * 阿里云OSS上传(默认是异步多文件上传)
     * @param urls
     */
    private void ossUpload(final List<String> urls) {

        if (urls.size() <= 0) {
            // 文件全部上传完毕,这里编写上传结束的逻辑,如果要在主线程操作,最好用Handler或runOnUiThead做对应逻辑
            return;// 这个return必须有,否则下面报越界异常,原因自己思考下哈
        }
        final String url = urls.get(0);
        if (TextUtils.isEmpty(url)) {
            urls.remove(0);
            // url为空就没必要上传了,这里做的是跳过它继续上传的逻辑。
            ossUpload(urls);
            return;
        }

        File file = new File(url);
        if (null == file || !file.exists()) {
            urls.remove(0);
            // 文件为空或不存在就没必要上传了,这里做的是跳过它继续上传的逻辑。
            ossUpload(urls);
            return;
        }
        // 文件后缀
        String fileSuffix = "";
        if (file.isFile()) {
            // 获取文件后缀名
            fileSuffix = file.getName().substring(file.getName().lastIndexOf("."));
        }
        // 文件标识符objectKey
        final String objectKey = "alioss_" + System.currentTimeMillis() + fileSuffix;
        // 下面3个参数依次为bucket名,ObjectKey名,上传文件路径
        PutObjectRequest put = new PutObjectRequest(Constant.BUCKET_NAME, objectKey, url);

        // 设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                // 进度逻辑
            }
        });
        // 异步上传
        OSSAsyncTask task = MyApp.getOSS().asyncPutObject(put,
                new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                    @Override
                    public void onSuccess(PutObjectRequest request, PutObjectResult result) { // 上传成功
                        urls.remove(0);
                        ossUpload(urls);// 递归同步效果
                    }

                    @Override
                    public void onFailure(PutObjectRequest request, ClientException clientExcepion,
                            ServiceException serviceException) { // 上传失败

                        // 请求异常
                        if (clientExcepion != null) {
                            // 本地异常如网络异常等
                            clientExcepion.printStackTrace();
                        }
                        if (serviceException != null) {
                            // 服务异常
                            Log.e("ErrorCode", serviceException.getErrorCode());
                            Log.e("RequestId", serviceException.getRequestId());
                            Log.e("HostId", serviceException.getHostId());
                            Log.e("RawMessage", serviceException.getRawMessage());
                        }
                    }
                });
        // task.cancel(); // 可以取消任务
        // task.waitUntilFinished(); // 可以等待直到任务完成
    }

OK,看懂了没,还是蛮简单的,代码注释的也很详细。多文件同步删除与上述上传逻辑属于同一个套路,改几个单词差不多就可以了。这里提醒下,阿里云oss是根据objectKey删除文件的,所以判断文件存不存在是使用官方的代码判断 :

boolean isExist = MyApp.getOSS().doesObjectExist(Constant.BUCKET_NAME, objectKey);

这次就不上传源码了,大家有什么疑问之处或需要源码可以直接回复我。

 2017年8月3日更新:

很多朋友都在问我一个请求能不能同时上传多张图片,我这边可能因为没有深入地研究官方文档,不能给大家作出肯定的回复。
But,个人认为没有必要提供这样的接口:首先,多图片一个请求同时上传需要消耗更多的CPU和内存资源(容易造成OOM);其次,漫长时间的网络连接,如果中间出现错误(网络,APP,系统出现问题)不仅前功尽弃,服务端还要删除这些tmp文件。

方案有没有?

这里提供简单的方案思路(基于本文上传方案的修改):
上文提到一个图片上传成功后会回调OSSCompletedCallback的onSuccess方法,那么我们可以在此记录被上传的图片的objectKey于List或Map中,上传结束后把这些objectKey集合通过一个请求反馈给App的服务端就可以了。

Excause Me?! 嗯!就这样!

© 版权声明
THE END
喜欢就支持以下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容