0

ユーザーが最大 760 個のファイル (合計で約 350MB) をダウンロードする必要があるアプリがあります。これらのファイルを圧縮することはできません。ルーズ ファイルとしてダウンロードする必要があります。

現在、Android Asynchronous Http Clientを使用して個々のファイルをダウンロードAsyncTaskし、プロセス全体を実行しています。

DownloadThreadバックグラウンドで何百ものファイルのダウンロードを処理するオブジェクトの例を次に示します。

public class DownloadThread extends AsyncTask<String,String,String> {

ArrayList<String> list;
AsyncHttpClient client;
String[] allowedContentTypes = new String[] { "audio/mpeg" };
BufferedOutputStream bos;
FileOutputStream fos;

@Override
protected String doInBackground(String... params) {
    DownloadTask task;
    for (String file : list) {
        //the "list" variable has already been populated with hundreds of strings
        task = new DownloadTask(file);
        task.execute("");
        while (!task.isdone)
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }

    return null;
}


class DownloadTask extends AsyncTask<String, String, String> {

    String character, filename;
    boolean isdone = false;

    public DownloadTask(String file) {
        //file = something like "Whale/sadwhale.mp3"
        character = file.split("/")[0];
        filename = file.split("/")[1];
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected void onPostExecute(String result) {
        if (!result.equals("Error")) {
                        //Do something on success
        }
        isdone = true;
    }

    @Override
    protected String doInBackground(String... str) {
        client = new AsyncHttpClient();
        client.get("http://some-site.com/sounds/" + character + "/"
                + filename, new BinaryHttpResponseHandler(
                allowedContentTypes) {
            @Override
            public void onSuccess(byte[] fileData) {
                try {
                    // Make file/folder and create stream
                    File folder = new File(Environment
                            .getExternalStorageDirectory()
                            + CharSelect.directory + character);
                    folder.mkdirs();
                    File dest = new File(folder, filename);
                    fos = new FileOutputStream(dest);
                    bos = new BufferedOutputStream(fos);
                    // Transfer data to file
                    bos.write(fileData);
                    bos.flush();
                    bos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        return "Success";
    }

}

}

DownloadThreadバックグラウンドで実行され、何百もの独自のAsyncTasks. タスクのダウンロードが完了するまで待機し、forダウンロードごとにループを続行します。

これはうまくいきます。一部のダウンロードが正しく終了しないか、まったく開始されないように見えます。760 回のダウンロードのリストのうち、平均 100 回のダウンロードが正常に完了したため、プロセスを再起動して、さらに 100 回のダウンロードが失敗するまで、さらに 100 回のダウンロードをダウンロードする必要があります。Thread.sleep(10)行が少し「ハッキー」に見えるので、これはタイミングの問題によるものだと感じています。

確かに、何百AsyncTasksもの別のものを呼び出すAsyncTaskことは、これを行うための最も効率的な方法ではありません。このタスクに適合するように、このコードを変更したり、サードパーティのソリューションを実装したりするにはどうすればよいですか?

4

2 に答える 2

3

DownloadManager API を試してください。これはあなたが必要とするものです。

于 2013-05-15T22:43:40.873 に答える