2014-01-23 62 views
0

我正在使用v3 api從兩個通道獲取youtube視頻的應用程序。我激發了兩個查詢:一個獲得視頻列表&另一個獲取視頻詳細信息列表(持續時間和視圖)。我使用asynctask來完成這些任務,但是任務並沒有在第一次嘗試時完成。我必須退出應用程序,然後在列表顯示之前重新打開。任何人都可以告訴我爲什麼會發生這種情況,如果我實施asynctask的方式有什麼問題?以下是我的Asynctask代碼。在doInBackground()中製作多個httpcall時,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

「第一次嘗試不完成」?你的意思是doInBackground()不完全完成它的任務?爲什麼你評論過「onPostExecute()」方法? –

+0

@法伊贊:是的,我的asynctask沒有完成。我必須退出應用程序,然後再打開它才能看到列表。 onPostExecute被評論是沒有使用,我已經刪除了相同..實際onPostExecute被寫入方式 –

+0

以上如何你可以說它不完整 – Sush

回答

2

我覺得你所有的http調用都應該在doInBackground()之內Method.Your在ui線程中調用postExecute()方法。所以你認爲你的async task沒有完成。實際上async task完成後調用postExecute()。對於你的呼叫,並在postExecute()再次打電話給你。 希望你清楚。

+0

我將所有的http調用移動到doInBackground(),但問題仍然存在。 onPostExecute()僅用於關閉pDialog。上面發佈了新的代碼。 –

+0

@SidM是對話變得無聊。還有一個你會試試catch塊。檢查你的日誌貓是否有任何問題與JSON解析。我的意思是json異常正在拋出或wt? – Sush

+0

是的pDialog正在被解僱,但佈局沒有得到渲染,所以我留下了一個黑色的屏幕,沒有數據。順便說一句,在對話結束後(20-30秒),網絡似乎已經使用了很長時間。沒有引發JSON解析的問題。只是佈局沒有得到渲染。 –

0

所有任務的大部分必須doInBackground(),因爲它是在一個單獨的線程中完成的,而onpostExecute()運行在主線程中完成。是否所有繁重的工作中doInBackground()並返回任何需要從這裏本身更新的用戶界面,並從onPostExecute()()

0

更新UI時asynk任務完成,然後在最後的太赫茲方法調用,這樣我只好解僱你添加此方法堂妹dailog這裏

@Override 
      protected void onPostExecute() { 
      super.onPreExecute(); 

      pDialog.dismiss(); 

    } 
+0

我應該在onPostExecute()開始時關閉pDialog還是在所有任務完成後結束? –

+0

在開始時應該沒問題。onPostExecute()用於更新UI。所以,你關閉pDialog並在用戶界面上顯示內容。 –

+0

onpost()會在所有進程完成後自動調用,所以不要擔心thz哥們在發佈後我們只是更新我們的UI –

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

+2

你無法在'onPostExecute'中獲得'JsonObject',你必須在'doInBackground '。這個工具導致'networkExceptionOnUiThread' –

+0

我可以在同一個doInBackground()內進行多個http調用,並將單個JSONArray中的所有結果返回到onPostExecute()? –

+0

@SidM來讀取,你必須從響應中獲得InputStream。並且數據流來自網絡。因此讀取涉及網絡操作 –

相關問題