繁体   English   中英

JAVA使用回调同步循环

[英]JAVA Synchronize cycle with callbacks

我有这个函数下载ArrayList中的所有文件,我想让它“同步”,我的意思是我想一次只下载一个文件。

如何让FOR循环等到文件下载后再下载其他文件?

public void downloadFiles(ArrayList<String> files, final String destinationFolder){
  for(String file:files){
    GoogleDrive.getInstance().readFile(file, GoogleDrive.FolderLocation.ROOT_FOLDER, new GoogleDrive.GoogleDriveReadFileCallback() {
         @Override
         public void successful(String title, byte[] content) {
           try {
             FileUtils.writeByteArrayToFile(new File(destinationFolder+File.pathSeparator+title), content);
           } catch (IOException e) {
             Log.e(TAG,"ERROR FileManager.downloadFiles: "+e.toString());
           }
        }
        @Override
        public void notFound() { }
        @Override
        public void error(String error) { }
      });
    }
}

这个问题听起来很简单; 但事实证明很难 这是为什么? 因为给定的代码以错误的方式处理。 我的意思是什么?

认为

GoogleDrive.getInstance().readFile(file,
  GoogleDrive.FolderLocation.ROOT_FOLDER, 
  new GoogleDrive.GoogleDriveReadFileCallback()

触发Google云端硬盘的异步读取; 竞争时,将调用该回调实例。 但是当我们仔细研究那个回调代码时 - 我们发现它缺少必要的部分:

  • 没有做任何类型的错误处理(提示:你知道这种方法何时出错)
  • 回调无法向外界“发出信号”“我完成了”。

因此:解决方案是完全重做那件事。 您可以创建一个实现所需接口的真实类; 并且回调实现可以有方法告诉您文件读取是否仍在进行,成功完成还是失败。

换句话说:你围绕GoogleDrive构建一个包装器 readFile() ; 而包装提供了同步阅读(可能是successfull()时被调用readFile()做-让你的包装可以简单地等待回调); 或者包装器可以返回某种Future

24小时后,answear太容易了,只是实现了一个监听器,每次旧的终止时都会开始新的下载(成功与否)并将其从列表中删除。 我不知道这是否是正确的方法,但它有效

interface FileManagerDownloadEvent{
    void downloadSuccessful(String fileName);
    void downloadNotFound(String fileName);
    void downloadError(String fileName,String error);
}

public class FileManager implements FileManagerDownloadEvent{

        private FileManagerDownloadEvent downloadEvent;
        private ArrayList<String> filesToDownload;
        private String destinationFolder;

        public FileManager(){
            this.downloadEvent=this;
        }

        private void download(){
            if(filesToDownload.size()!=0) {
                final String file=filesToDownload.get(0);
                filesToDownload.remove(0);

                GoogleDrive.getInstance().readFile(file, GoogleDrive.FolderLocation.ROOT_FOLDER, new GoogleDrive.GoogleDriveReadFileCallback() {
                    @Override
                    public void successful(String title, byte[] content) {
                        try {
                            FileUtils.writeByteArrayToFile(new File(destinationFolder+File.separator+title), content);
                            downloadEvent.downloadSuccessful(destinationFolder+File.separator+title);
                        } catch (Exception e) {
                            Log.e(TAG,"ERROR FileManager.downloadFiles: "+e.toString());
                        }
                    }

                    @Override
                    public void notFound() {
                        downloadEvent.downloadNotFound(file);
                    }

                    @Override
                    public void error(String error) {
                        downloadEvent.downloadError(file,error);
                    }
                });
            }
        }

        @Override
        public void downloadSuccessful(String filePath) {
            Log.d(TAG,"downloadSuccessful: "+filePath);
            download();
        }

        @Override
        public void downloadNotFound(String fileName) {
            Log.e(TAG,"downloadNotFound: "+fileName);
            download();
        }

        @Override
        public void downloadError(String fileName,String error) {
            Log.e(TAG,"downloadError: "+fileName+" --> "+error);
            download();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM