2017-05-03 48 views
1

我有这个功能下载ArrayList中的所有文件,我想使这个“同步”,我的意思是,我想只下载一个文件,在时间。JAVA同步周期,回调

我怎样才能使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) { } 
     }); 
    } 
} 
+0

奇怪的是,我通常开始编写代码,以顺序方式工作;之后再添加并行性。有趣的方法首先解决更复杂的问题;-) – GhostCat

+0

API文档中没有任何内容告诉你是否可以同步完成读取? 另外,你可以在回调中具体的读到下一个元素,并以这种方式序列化每个请求。 –

+0

还是一个有趣的问题;有我的投票! – GhostCat

回答

2

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

假设

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

触发异步从谷歌驱动器中读取;并且竞争时,该回调实例将被调用。但是,当我们仔细看看那个回调代码 - 我们发现它缺少基本部分:

  • 进行任何类型的错误处理(暗示:你有没有知道什么时候出事错用这种方法)
  • 回调有没有办法“信号”外面的世界“我是做了”。

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

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

+0

我同意你的解决方案不完整。但我不认为这回答了OP提出的问题。 –

+0

我认为那就是现场。 –

+0

先生,谢谢你,先生。 – GhostCat

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