JAVA使用回调同步循环

时间:2017-05-03 16:38:57

标签: java callback wait cycle

我有这个函数下载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) { }
      });
    }
}

2 个答案:

答案 0 :(得分:2)

这个问题听起来很简单;但原来是很难。这是为什么?因为给定的代码是以错误方式执行的。我的意思是什么?

假设那个

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

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

  • 进行任何类型的错误处理(提示:当此方法出现问题时,您没有想法)
  • 回调无法发出信号&#34;对外界&#34;我已经完成了#34;。

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

换句话说:您围绕GoogleDrive readFile()构建包装;并且该包装器提供同步读取(在successfull()完成时可能会调用readFile() - 因此您的包装器可以简单地等待该回调);或者包装器可以返回某种Future

答案 1 :(得分:1)

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();
        }
    }