我正在开发一款使用v3 api从两个频道获取youtube视频的应用。我发了两个查询:一个用于查看视频列表&另一个是获取视频详细信息列表(持续时间和视图)。我使用asynctask执行这些操作,但任务在第一次尝试时无法完成。我必须退出应用程序,然后在显示列表之前重新打开。任何人都可以告诉我为什么会发生这种情况,以及我实施asynctask的方式是否有任何问题?下面是我的Asynctask代码。
private class Fetchlist extends AsyncTask<String, String, JSONArray> {
private ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(VideoListDemoActivity.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected JSONArray doInBackground(String... params) {
JSONArray jsonArray1 = null;
JSONArray jsonArray2 = null;
JSONArray jsonArrayFinal = null;
try {
String urlvideos1 = "https://www.googleapis.com/youtube/v3/search?key=xyz&channelId=abc&part=snippet&order=viewCount&maxResults=20";
String urlvideos2 = "https://www.googleapis.com/youtube/v3/search?key=xyz2&channelId=abc2&part=snippet&order=viewCount&maxResults=20";
JSONParser jParser = new JSONParser();
JSONObject jsonVideos1 = jParser.getJSONFromUrl(urlvideos1);
JSONObject jsonVideos2 = jParser.getJSONFromUrl(urlvideos2);
jsonArray1 = jsonVideos1.getJSONArray("items");
jsonArray2 = jsonVideos2.getJSONArray("items");
jsonArrayFinal = concatArray(jsonArray1, jsonArray2);
for (int i = 0; i < jsonArrayFinal.length(); i++) {
JSONObject jsonID = jsonArrayFinal.getJSONObject(i);
Log.d("Async Values", "inside do in background");
try {
JSONObject jsonVid = jsonID.getJSONObject("id");
JSONObject jsonSnippet = jsonID
.getJSONObject("snippet");
String title = jsonSnippet.getString("title");
String videoid = jsonVid.getString("videoId");
try {
String urltwo = "https://www.googleapis.com/youtube/v3/videos?id="
+ videoid
+ "&key=xyz&part=snippet,contentDetails,statistics,status";
JSONParser jParsertwo = new JSONParser();
JSONObject jsontwo = jParsertwo
.getJSONFromUrl(urltwo);
// JSONObject jsonID = json.getJSONObject("items");
JSONArray jsonArraytwo = jsontwo
.getJSONArray("items");
JSONObject jsonIDtwo = jsonArraytwo
.getJSONObject(0);
JSONObject jsonView = jsonIDtwo
.getJSONObject("statistics");
JSONObject jsonDuration = jsonIDtwo
.getJSONObject("contentDetails");
String Duration = jsonDuration
.getString("duration");
String strDuration = Duration;
SimpleDateFormat df = new SimpleDateFormat(
"'PT'mm'M'ss'S'");
String youtubeDuration = Duration;
Date d = df.parse(youtubeDuration);
Calendar c = new GregorianCalendar();
c.setTime(d);
c.setTimeZone(TimeZone.getDefault());
int minduration = c.get(Calendar.MINUTE);
int secduration = c.get(Calendar.SECOND);
String strMin = String.valueOf(minduration);
String strSec = String.valueOf(secduration);
// Toast.makeText(VideoListDemoActivity.this,
// strMin, Toast.LENGTH_LONG).show();
String viewcount = jsonView.getString("viewCount");
// Toast.makeText(VideoListDemoActivity.this,
// viewcount, Toast.LENGTH_LONG).show();
title = jsonSnippet.getString("title")
+ "\n\nViews: " + viewcount + " Length: "
+ strMin + ":" + strSec;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("JSON msg", e.toString());
}
if (!list.contains(title)) {
list.add(new VideoEntry(title, videoid));
}
}
catch (Exception e) {
Log.d("Do in background", e.toString());
}
}
} catch (Exception e) {
Log.d("Do in background", e.toString());
}
return jsonArrayFinal;
}
protected void onPostExecute(JSONArray jsonArrayFinal) {
pDialog.dismiss();
layout();
}
}
以下是布局代码。它是youtube api演示的一部分并实现了片段。
private void layout() {
boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
listFragment.getView().setVisibility(
isFullscreen ? View.GONE : View.VISIBLE);
listFragment.setLabelVisibility(isPortrait);
closeButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE);
if (isFullscreen) {
videoBox.setTranslationY(0); // Reset any translation that was
// applied in portrait.
setLayoutSize(videoFragment.getView(), MATCH_PARENT, MATCH_PARENT);
setLayoutSizeAndGravity(videoBox, MATCH_PARENT, MATCH_PARENT,
Gravity.TOP | Gravity.LEFT);
} else if (isPortrait) {
setLayoutSize(listFragment.getView(), MATCH_PARENT, MATCH_PARENT);
setLayoutSize(videoFragment.getView(), MATCH_PARENT, WRAP_CONTENT);
setLayoutSizeAndGravity(videoBox, MATCH_PARENT, WRAP_CONTENT,
Gravity.BOTTOM);
} else {
videoBox.setTranslationY(0); // Reset any translation that was
// applied in portrait.
int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp);
setLayoutSize(listFragment.getView(), screenWidth / 4, MATCH_PARENT);
int videoWidth = screenWidth - screenWidth / 4
- dpToPx(LANDSCAPE_VIDEO_PADDING_DP);
setLayoutSize(videoFragment.getView(), videoWidth, WRAP_CONTENT);
setLayoutSizeAndGravity(videoBox, videoWidth, WRAP_CONTENT,
Gravity.RIGHT | Gravity.CENTER_VERTICAL);
}
}
答案 0 :(得分:2)
我认为你所有的http调用都应该在doInBackground()
Method.Your中,通过将它们放在postExecute()
方法中来调用ui线程。所以你认为你的async task
没有完成。实际上async task
完成后会调用回调postExecute()。对你来说,它会在postExecute()
你的http调用中再次被调用。
希望你明白。
答案 1 :(得分:0)
所有大部分任务必须在doInBackground()
中完成,因为它是在一个单独的线程上完成的,而onpostExecute()
在主线程上运行。完成doInBackground()
中所有繁重的工作,并从此处返回更新用户界面所需的所有内容,并从onPostExecute()()
更新您的用户界面
答案 2 :(得分:0)
当asynk任务完成时添加此方法,然后在最后一次调用thz方法,所以你必须在这里解雇你的dailog
@Override
protected void onPostExecute() {
super.onPreExecute();
pDialog.dismiss();
}
答案 3 :(得分:0)
这样做:
在后执行中:
protected void onPostExecute(JSONArray JSON) {
pDialog.dismiss();
try{
for (int i=0; i<JSON.length(); i++)
{
JSONObject jsonID = JSON.getJSONObject(i);
// do what you want
}
}
无需一次又一次地调用url