2014-03-06 48 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()