2013-04-12 33 views
1

我上一個Android應用程序執行的HTTP POST請求工作,我跟着教程導致的android.os.NetworkOnMainThreadException的Android的AsyncTask:如何處理返回類型

原代碼是像這個。

public class JSONParser { 

static InputStream is = null; 
static JSONObject jObj = null; 
static String json = ""; 

// constructor 
public JSONParser() { 

} 

public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) { 

    // Making HTTP request 
    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(url); 
     httpPost.setEntity(new UrlEncodedFormEntity(params)); 

     HttpResponse httpResponse = httpClient.execute(httpPost); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     is = httpEntity.getContent(); 

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       is, "iso-8859-1"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
     is.close(); 
     json = sb.toString(); 
     Log.e("JSON", json); 
    } catch (Exception e) { 
     Log.e("Buffer Error", "Error converting result " + e.toString()); 
    } 

    // try parse the string to a JSON object 
    try { 
     jObj = new JSONObject(json);    
    } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data " + e.toString()); 
    } 

    // return JSON String 
    return jObj; 

} 
} 

而這個類被調用這一行。

JSONObject json = jsonParser.getJSONFromUrl(loginURL, params); 

將此更改爲AsyncTask類後,代碼如下所示。

class JSONParser extends AsyncTask<String, Void, JSONObject>{ 

static InputStream is = null; 
static JSONObject jObj = null; 
static String json = ""; 

// variables passed in: 
String url; 
List<NameValuePair> params; 

// constructor 
public JSONParser(String url, List<NameValuePair> params) { 
    this.url = url; 
    this.params = params; 
} 

@Override 
protected JSONObject doInBackground(String... args) { 
    // Making HTTP request 
     try { 
      // defaultHttpClient 
      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpPost httpPost = new HttpPost(url); 
      httpPost.setEntity(new UrlEncodedFormEntity(params)); 

      HttpResponse httpResponse = httpClient.execute(httpPost); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      is = httpEntity.getContent(); 


     } catch (UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        is, "iso-8859-1"), 8); 
      StringBuilder sb = new StringBuilder(); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
      is.close(); 
      json = sb.toString(); 
      Log.e("JSON", json); 
     } catch (Exception e) { 
      Log.e("Buffer Error", "Error converting result " + e.toString()); 
     } 

     // try parse the string to a JSON object 
     try { 
      jObj = new JSONObject(json);    
     } catch (JSONException e) { 
      Log.e("JSON Parser", "Error parsing data " + e.toString()); 
     } 

     // return JSON String 
     return jObj; 
} 

@Override 
protected void onPostExecute(JSONObject jObj) { 
    return; 
}  
} 

我的問題是,如何從這個新的AsyncTask類返回JSONObject?我可以看到,jObjdoInBackground()返回,但我不知道在那裏它被送回。

我需要修改什麼或如何調用我的新JSONParser類,以便返回JSONObject

回答

0

我可以看到jObj被返回doInBackground(),但我不是 確定它返回的位置。

doinBackground()的結果作爲onPostExecute()中的參數接收。你在doinBackground()中返回一個json對象,它是onPostExecute()的一個參數。

@Override 
protected void onPostExecute(JSONObject jObj) { 
return; 
} 

使用

new JSONParser().execute("url); 
class JSONParser extends AsyncTask<String, Void, JSONObject>{ 

    //string parameter to doInBackground() 
    //JSONObject - result returned in doInBackground() received as a param in onPostExecute() 
} 

您也可以通過paramters您的AsyncTask

new JSONParser("url",params).execute(); 

在你的AsyncTask的構造函數;

String url; 
List<NameValuePair> params; 

// constructor 
public JSONParser(String url, List<NameValuePair> params) { 
this.url = url; 
this.params = params; 
} 
+0

嗯。我仍然不確定如何使用舊參數來調用這個類。我試着做'JSONObject json = new JSONParser(loginURL,params).execute();'它說JSONParser的返回類型不是JSONObject ...是不是它返回的是什麼? – Christian

+0

execute()不返回任何值。請記住,AsyncTask異步執行*,意味着它將在稍後返回並調用'onPostExecute()' – dmon

+0

,但是您返回一個值,如doInbAckground()中的字符串,它是在標題下的onPostExecute() – Raghunandan

0

doInBackground方法

@Override 
protected JSONObject doInBackground(String... args) { 

return jObj; 

}

你回你的JsonObject

@Override 
protected void onPostExecute(JSONObject jObj) { 

    // Here you get your return JsonObject 
} 
0

異步任務有3個attribures

Params, the type of the parameters sent to the task upon execution. 

Progress, the type of the progress units published during the background computation. 

Result, the type of the result of the background computation. 

你需要明白的一點是,要創建異步任務類的物體雖然調用new JSONParser(loginURL, params);

解決的辦法是,在你的異步類中創建一個公共結果變量和類對象上調用​​然後從該對象訪問該公共對象。

+0

好吧,我想我現在明白了。那麼我會聲明一個像'public static JSONObject jObj = null'這樣的全局JSONObject,那麼它可以在我的應用程序的任何地方訪問?另外,如果我的應用程序的另一部分期望jObj不爲null,Android是否知道要等到jObj被設置? – Christian

+0

我不會推薦使用一個類中的靜態變量在其他類中調用,因爲在某些情況下,android會重新創建活動或殺死後臺活動。解析Json並將細節存儲在像dB這樣的持久存儲中或在onSaveInstanceState()和onRestoreSavedInstance中管理數據會更好。 –

+0

我有一個** UserFunctions **類,最初打算調用'getJSONFromURL()'(在我的原始JSONParser類中,在我的問題的頂部),並存儲和使用其JSONObject返回值。我只是試圖將發送到'onPostExecute()'的JSONObject發送回** UserFunctions **類。但從這裏的答案,我得到的印象是我需要將一些UserFunctions功能移到'onPostExecute()'中。這就是我現在要做的事情,我正在使用AsyncTask? – Christian

1

看看這段代碼,它可能會讓你瞭解如何處理JSON對象的解析。我現在只是發佈onPostExecute函數,因爲你似乎已經正確地計算了所有其他的函數。

至於您對doInBackground中的數據對象返回的位置有疑問,它會自動發送到onPostExecute,您可以在其中進一步解析它。

  @Override 
    protected void onPostExecute(JSONObject result) 
    { 
     try 
     { 
      JSONObject data = result.getJSONObject("data"); 
         // whatever your JSON tag may be, in this case its data. 

      if (data.isNull("data")) 
      { 
         // action to handle null JSON object. 
      }    
      else 
      { 
       JSONArray jarray = data.getJSONArray("data"); 
       int len=jarray.length(); 
       for (int i = 0; i < jarray.length(); i++) 
       { 
       JSONObject obj = (JSONObject) jarray.get(i); 

      String instanceName = obj.getString("instanceName"); 
         //extract data by whatever tag names you require, in this case instanceName.  
      } 
     } 
} 
     catch (JSONException je) 
     { 
      je.printStackTrace(); 
      Log.d(TAG, "Error: " + je.getMessage()); 
     }  
    } 
} 
相關問題