【问题标题】:JAVA Synchronize cycle with callbacksJAVA 与回调同步循环
【发布时间】:2017-05-03 16:38:56
【问题描述】:

我有这个功能可以下载 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) { }
      });
    }
}

【问题讨论】:

  • 奇怪,我通常开始编写以顺序方式工作的代码;在后来添加并行性之前。首先解决更复杂的问题的有趣方法;-)
  • API 文档中没有任何内容可以告诉您是否可以同步完成?此外,您可以在回调中指定对下一个元素的读取,并以这种方式序列化每个请求。
  • 还是个有趣的问题;投我一票!

标签: java callback wait cycle


【解决方案1】:

这个问题听起来很简单;但结果却是困难。这是为什么?因为给定的代码以错误的方式做事。这是什么意思?

假设

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

触发从 Google Drive 读取 异步竞争时,该回调实例将被调用。但是,当我们仔细查看该回调代码时 - 我们发现它缺少重要部分:

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

因此:解决方案是彻底返工。您可以创建一个实现所需接口的真实类;并且该回调实现可能具有告诉您文件读取是否仍在进行中、成功完成还是失败的方法。

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

【讨论】:

  • 我同意您的观点,即解决方案不完整。但我认为这并不能回答 OP 提出的问题。
  • 我认为这很合适。
  • 抱歉耽搁了,感谢您的回复,但问题很简单,我有一个要下载的文件名称列表,我现在想要的只是一个接一个地下载文件而不是全部立即像现在一样。至于包装器,它返回成功,notFound 和错误仅此而已
  • 您的答案与我的问题不符,但由于您花时间写了 190 个单词,我会支持您的答案
  • 感谢!我将看到如何使这两个答案的对齐方式更加明显:-)
【解决方案2】:

24 小时后,答案太简单了,只需实现一个侦听器,每次旧下载终止时(无论成功与否)都会启动新下载并将其从列表中删除。我不知道这是否是正确的方法,但它有效

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

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 2013-02-16
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多