2014-03-06 46 views
0

我的類從web讀取json字符串,並且收集的字符串填充hashmap。 我正在使用AsyncTask來讀取進度對話框的數據,讓設備「正在工作」的用戶。 這是我的類:Android異步任務從Web獲取json字符串

class ArmoryAsyncProgress extends AsyncTask<String, Void, Void> { 

    private Context   mContext; 
    private ProgressDialog mProgressDialog; 
    private String tempRes; 

    public ArmoryAsyncProgress(Context mContext) 
    { 
     this.mContext = mContext; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mProgressDialog = ProgressDialog.show(mContext, "Carica!", "Gira!"); 
    } 

    @SuppressLint("NewApi") 
    @Override 
    protected String doInBackground(String... sUrl) { 
     try { 
      URL json = new URL(Utility.BASE_URL + "api.php?action=armory&guid="+pGuid); 
      BufferedReader in = new BufferedReader(
        new InputStreamReader(
          json.openStream())); 
      String input; 
      while((input = in.readLine()) != null) 
       Result += input; 

      json = new URL(Utility.BASE_URL + "api.php?action=armory_stats&guid="+pGuid); 
      in = new BufferedReader(
        new InputStreamReader(
          json.openStream())); 
      input = ""; 
      String ret = ""; 
      while((input = in.readLine()) != null) 
       ret += input; 

      tempRes = Result + "Ø" + ret; 
      String debug = tempRes; 
     } 
     catch(MalformedURLException e){ 
      e.printStackTrace(); 
     } 
     catch (IOException ex) { 
      ex.printStackTrace(); 
     } 

     ActivityArmory.result = tempRes; 
     return null; 
    } 

    protected void onPostExecute(String result) { 

     /*********************************************************************************/ 
     try 
     { 
      String ret; 
      while(result == null) 
       Thread.sleep(500); 
      String[] temp = result.split("Ø"); 
      pJSON = temp[0]; 
      ret = temp[1]; 

      JSONObject pl = new JSONObject(ret); 
      stats.put("Level", pl.getString("level")); 
      stats.put("Classe", pl.getString("class")); 
      stats.put("Name", pl.getString("pname")); 
      stats.put("Race", pl.getString("race")); 

      stats.put("health", pl.getString("health")); 
      stats.put("power", pl.getString("power1")); 
      stats.put("gname", pl.getString("gname")); 
      stats.put("pnote", pl.getString("pnote")); 
      stats.put("offnote", pl.getString("offnote")); 
      stats.put("rname", pl.getString("rname")); 

      JSONArray jObject = new JSONArray(pJSON); 

      for (int i = 0; i < jObject.length(); i++) { 
       JSONObject item = jObject.getJSONObject(i); 
       ArmoryElement i1 = new ArmoryElement(
         "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg", 
         item.getInt("itemID"), item.getInt("quality")); 

       el.put(item.getString("itemType"), i1); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    /****************************************************************/ 

     mProgressDialog.dismiss(); 
    } 
} 

,這是調用類:

new ArmoryAsyncProgress().execute(pGuid+""); 

「執行」方法調用我調用另一個函數,用於格式化和之後從網絡獲取的顯示用數據。 我的問題是沒有顯示在Async類中聲明的progressDialog,並且在執行完成之前調用execute之後調用的函數被調用(使用某些Log我發現第二個函數中的日誌在doInBackground完成之前顯示)

我也嘗試過.get方法,它凍結了主線程並阻止函數被調用,但我無法顯示progressdialog。

在此先感謝

+0

正常情況下,異步任務工作異步。只有當他輸入onPostExecute時,才能確定異步任務已終止。 – MemLeak

+0

和我能做些什麼來防止代碼被執行? – Mattiag

+0

我發佈了真正的問題,你應該傳遞allready解析對象,只做gui的東西。但檢查我的答案,問題是你的返回null。 – MemLeak

回答

0

壞的部分是:

protected void onPostExecute(String result) { 

    /*********************************************************************************/ 
    try 
    { 
     String ret; 
     while(result == null) 
      Thread.sleep(500); 

由於這種運行在UI線程,將與嚴格模式發生衝突。

protected void onPostExecute(String result) { 
if(result!=null){ 
    /*********************************************************************************/ 
    try 
    { 
     String ret; 

     String[] temp = result.split("Ø"); 
     pJSON = temp[0]; 
     ret = temp[1]; 

     JSONObject pl = new JSONObject(ret); 
     stats.put("Level", pl.getString("level")); 
     stats.put("Classe", pl.getString("class")); 
     stats.put("Name", pl.getString("pname")); 
     stats.put("Race", pl.getString("race")); 

     stats.put("health", pl.getString("health")); 
     stats.put("power", pl.getString("power1")); 
     stats.put("gname", pl.getString("gname")); 
     stats.put("pnote", pl.getString("pnote")); 
     stats.put("offnote", pl.getString("offnote")); 
     stats.put("rname", pl.getString("rname")); 

     JSONArray jObject = new JSONArray(pJSON); 

     for (int i = 0; i < jObject.length(); i++) { 
      JSONObject item = jObject.getJSONObject(i); 
      ArmoryElement i1 = new ArmoryElement(
        "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg", 
        item.getInt("itemID"), item.getInt("quality")); 

      el.put(item.getString("itemType"), i1); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
/****************************************************************/ 
} 
    mProgressDialog.dismiss(); 
} 

偶數貝德部分是:

return null; 
在doInBackground方法

然而

,這應該工作:

class ArmoryAsyncProgress extends AsyncTask<String, Void, Void> { 

    private Context   mContext; 
    private ProgressDialog mProgressDialog; 
    private String tempRes; 

    public ArmoryAsyncProgress(Context mContext) 
    { 
     this.mContext = mContext; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mProgressDialog = ProgressDialog.show(mContext, "Carica!", "Gira!"); 
    } 

    @SuppressLint("NewApi") 
    @Override 
    protected String doInBackground(String... sUrl) { 
     try { 
      URL json = new URL(Utility.BASE_URL + "api.php?action=armory&guid="+pGuid); 
      BufferedReader in = new BufferedReader(
        new InputStreamReader(
          json.openStream())); 
      String input; 
      while((input = in.readLine()) != null){ 
       Result += input; 
      } 
      json = new URL(Utility.BASE_URL + "api.php?action=armory_stats&guid="+pGuid); 
      in = new BufferedReader(
        new InputStreamReader(
          json.openStream())); 
      input = ""; 
      String ret = ""; 
      while((input = in.readLine()) != null){ 
       ret += input; 
      } 
      tempRes = Result + "Ø" + ret; 
      String debug = tempRes; 
     } 
     catch(MalformedURLException e){ 
      e.printStackTrace(); 
     } 
     catch (IOException ex) { 
      ex.printStackTrace(); 
     } 

     ActivityArmory.result = tempRes; 
     return tempRes; 
    } 

    protected void onPostExecute(String result) { 
     if(result!=null) 
     /*********************************************************************************/ 
     try 
     { 
      String ret; 
      String[] temp = result.split("Ø"); 
      pJSON = temp[0]; 
      ret = temp[1]; 

      JSONObject pl = new JSONObject(ret); 
      stats.put("Level", pl.getString("level")); 
      stats.put("Classe", pl.getString("class")); 
      stats.put("Name", pl.getString("pname")); 
      stats.put("Race", pl.getString("race")); 

      stats.put("health", pl.getString("health")); 
      stats.put("power", pl.getString("power1")); 
      stats.put("gname", pl.getString("gname")); 
      stats.put("pnote", pl.getString("pnote")); 
      stats.put("offnote", pl.getString("offnote")); 
      stats.put("rname", pl.getString("rname")); 

      JSONArray jObject = new JSONArray(pJSON); 

      for (int i = 0; i < jObject.length(); i++) { 
       JSONObject item = jObject.getJSONObject(i); 
       ArmoryElement i1 = new ArmoryElement(
         "http://wow.zamimg.com/images/wow/icons/large/" + item.getString("itemIMG") + ".jpg", 
         item.getInt("itemID"), item.getInt("quality")); 

       el.put(item.getString("itemType"), i1); 
      } 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    /****************************************************************/ 
    } 
     mProgressDialog.dismiss(); 
    } 
} 
1

調用後執行的函數被調用在執行完成之前

這是正常的,因爲AsyncTasks是異步的,這意味着它們將在後臺運行並允許其他代碼繼續運行。爲了解決這個問題,

  1. 如果任務是一個內部類的Activity,你可以調用 功能要運行它onPostExecute()

  2. 完成後,如果沒有,那麼你可以使用interfaceActivity完成後提供回調 。 See this answer for an example on interface

爲什麼ProgressDialog沒有顯示,我不太清楚,但你可以通過onPostExecute()去除Thread.sleep()作爲開始,這將使你的主線程睡眠。我看到的唯一需要在onPostExecute()中是mProgressDialog.dismiss()。其餘的可以在doInBackground()完成。

此外,你是正確的使用.get(),它會凍結你的UI Thread

1

PostExecute()使用不能執行大運算,使用像在doInBackground JSON解析那些繁重的操作,你必須改變doInBackground的返回值。要顯示UI,即在textview或listview中顯示,請使用PostExecute()