私のアンドロイドアプリでVimeo APIを使用して、特定のvimeoビデオのリンクを自分のVimeo Proアカウントから取得し、AsyncTaskを通じてこのビデオをダウンロードします。ファイルの読み書きは問題ありませんが、リンクを引っ張ってそのメソッドに渡すのに問題があります。次のようにAsyncTask内で非同期ネットワークタスクを待つ最善の方法
コードは:コードの端部に向かって
class DownloadFileFromURL extends AsyncTask<String, String, String> {
...
@Override
protected String doInBackground(final String... args) {
// args[1]/name is the output file name
String name = args[1];
...
// pos is the position within the vimeo channel's array
final int pos = Integer.parseInt(args[3]);
//Here is the main code, args[2] is the channel id for
//the specific vimeo channel that the code
//needs to pull the video files from.
VimeoClient.getInstance().fetchNetworkContent(args[2], new ModelCallback<VideoList>(VideoList.class) {
@Override
public void success(VideoList videoList) {
//If the video exists, get the video object,
//and then get the video files related to that object from download[].
if (videoList != null && videoList.data != null && !videoList.data.isEmpty()) {
Video video = videoList.data.get(pos);
ArrayList<VideoFile> videoFiles = video.download;
// Get the video file, and then get it's link, store as string.
if(videoFiles != null && !videoFiles.isEmpty()) {
VideoFile videoFile = videoFiles.get(2); // you could sort these files by size, fps, width/height
String link = videoFile.getLink();
**link = [test direct link to mp4];
DownloadFile(link, args[1]);**
}
}
}
...
});
**//String link = [test direct link to mp4];
//DownloadFile(link, args[1]);**
}
...
}
文字列変数とDownloadFile(文字列リンク、列outputName)ラインは私の主要な問題です。私はvideoFile.getLink()からリンクを出力し、それをコードのテストリンクとして使用しました。 vimeoClient.fetchNetworkContentの外でstring link = xxx、およびDownloadFileを実行すると、コードはfetchNetworkContent()メソッドの中に置かれているときに動作し、NetworkOnMainThreadExceptionにヒットします。
問題は、DownloadFile()を実行する前にリンクを取得する必要があることです。 fetchNetworkContent内でこれを修正する方法はありますか?または、NetworkFetchContentが完了するまでコメントアウトされているDownloadFile()の前にシステムを強制的に待機させる方法がありますか?
EDIT:私は、asyncTasksを連鎖させるcricket_007の答えに基づいてコードを更新しました。 2番目のAsyncTaskを作成するのではなく、ロジックシステムで同じタスクをループすることにしました。
最初に実行しているDownloadFileFromURL()は基本的に質問しますが、私はどのような情報を与えていますか?
URLを指定すると、DownloadFile(url、outputsFileName)が実行されます。 そうでない場合、キーワード "vimeo"を受け取ると、vimeoClientを使用してリンクを検索し、その中からDownloadFileFromURL(vimeoLinkURL、outputsFileName)を実行します。私は論理木を使ったばかりだと思います。
class DownloadFileFromURL extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* Downloading file in background thread
*/
@Override
protected String doInBackground(final String... args) {
final String name = args[1];
// Check if this is already a url link ending in .mp4
if(FilenameUtils.isExtension(args[0], "mp4")){
DownloadFile(args[0], args[1]);
}
//If not, is it a vimeo video? Check with keyword "vimeo"
else if (args[0].contains("vimeo")){
final int pos = Integer.parseInt(args[3]);
VimeoClient.getInstance().fetchNetworkContent(args[2], new ModelCallback<VideoList>(VideoList.class) {
@Override
public void success(VideoList videoList) {
Log.d("VimeoClient", "Success in VimeoList Reading");
if (videoList != null && videoList.data != null && !videoList.data.isEmpty()) {
Video video = videoList.data.get(pos);
ArrayList<VideoFile> videoFiles = video.download;
if(videoFiles != null && !videoFiles.isEmpty()) {
VideoFile videoFile = videoFiles.get(2); // you could sort these files by size, fps, width/height
String link = videoFile.getLink();
new DownloadFileFromURL().execute(link, args[1], args[2], args[3]);
}
}
}
@Override
public void failure(VimeoError error) {
Log.d("VimeoError", "Failure in VideoList Reading in VideoDownloader class");
}
});
// return null so that the Toast is not created for completion
// since this ends in DownloadFile()
return null;
}
return name;
}
@Override
protected void onPostExecute(String fileName) {
if(fileName != null) {
Toast.makeText(mContext, "Completed download of " + fileName, Toast.LENGTH_LONG).show();
}
}
}
最終的なコードではなく、正しい答えとしてマークしましたが、私が使用した特定のコードよりもはるかに有益です。私のコードはこのユースケースでは私の特定のソリューションに特有ですが、彼の説明は本当の解決策でした。
私はおそらく 'ModelCallBack#success()'がUIスレッドで呼び出されていると思います。私は、 'AsyncTask'で' fetchNetworkContent() '呼び出しをラップするのではなく、UIスレッド上で直接呼び出すことができます(別のスレッドで実行する必要があります) 'メソッドを呼び出して' DownloadFile() 'を呼び出します。 – Clyde