2017-05-03 18 views
1

ArrayList内のすべてのファイルをダウンロードするこの機能を持っています。これを同期させるには、1つのファイルしかダウンロードしません。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() 

がトリガーことを前提としてい非同期 Googleドライブから読み取ります。 の競合では、そのコールバックインスタンスが呼び出されます。我々はそのコールバックコードに近い外観を持っている場合しかし - 私たちはそれが重要な部分が欠落していることを見つける:

  • それはではありません(ヒントエラー処理のいずれかの種類をやって:あなたはを持っている何かが行っていないアイデアをこのアプローチでは間違っている)
  • コールバックには、「完了しました」という外部世界への「通知」の手段がありません。

したがって、解決策は、そのことを完全に修正することです。必要なインターフェイスを実装する実際のクラスを作成することができます。そのコールバック実装には、ファイルの読み込みがまだ進行中であるか、正常に完了したか、失敗したかを示すメソッドが含まれている可能性があります。

つまり、GoogleドライブreadFile()の周りにラッパーを作成します。そのラッパーは同期読み取りを提供します(おそらくsuccessfull()readFile()が完了したときに呼び出されるため、ラッパーは単純にそのコールバックを待つことができます)。またはラッパーは何らかの種類のFutureを返す可能性があります。

+0

解決策が不完全であることに私は同意します。しかし、私はこれがOPによって提起された質問に答えるとは思わない。 –

+0

私はその場に出ると思います。 –

+0

先生ありがとうございました。 – GhostCat

1

24時間後には、answerearが簡単すぎました。古いものが終了するたびに新しいダウンロードを開始して(成功したかどうかにかかわらず)リスナを実装してリストから削除しました。これが正しい方法であるかどうかわかりませんが、それはうまくいくのですか?

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(); 
     } 
    } 
関連する問題