在doInBackground()中创建多个httpcall时,Asynctask无法完成

时间:2014-01-23 05:08:51

标签: android android-asynctask

我正在开发一款使用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);
}

}

4 个答案:

答案 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