2013-04-12 4 views
1

Я работаю на Android приложение, которое выполняет запрос POST в HTTP, и учебник я следовал был в результате чего android.os.NetworkOnMainThreadExceptionAndroid AsyncTask: Как обрабатывать возвращаемый тип

The оригинальный код было что-то вроде это.

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; 
}  
} 

Мой вопрос, как я могу вернуть JSONObject из этого нового AsyncTask класса? Я могу видеть, что jObj возвращается в doInBackground(), но я не знаю, где он возвращается к.

Что мне нужно изменить или как мне нужно позвонить моему новому классу JSONParser, чтобы он возвращал JSONObject?

ответ

0

Я могу видеть, что jObj возвращается в doInBackground() но я не уверен, где он возвращается к.

Результат doinBackground() принимается как параметр в onPostExecute(). Вы возвращаете объект json в doinBackground(), который является параметром 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);

Решение состоит в том, что создать переменный общественный результат в классе асинхронного и вызов execute() на объекте класса а затем получить доступ к объекту public из объекта.

+0

Хорошо, думаю, теперь я понимаю. Так я объявляю глобальный JSONObject, такой как public public JSONObject jObj = null, тогда его можно было бы получить в любом месте моего приложения? Кроме того, если другая часть моего приложения ожидает, что jObj не будет равна нулю, будет ли Android знать, ждать, пока не будет установлен jObj? – Christian

+0

Я не рекомендую использовать статическую переменную в одном классе для вызова в другом классе, так как в некотором условии андроид будет воссоздавать действия или убивать фоновые действия. Лучше разобрать Json и сохранить данные в постоянном хранилище, например, в dB или управлять вашими данными в onSaveInstanceState() и onRestoreSavedInstance. –

+0

У меня есть класс ** UserFunctions **, который изначально предполагался для вызова 'getJSONFromURL()' (в моем исходном классе JSONParser, в верхней части моего вопроса) и хранить и работать со своим возвращаемым значением JSONObject. Я просто пытаюсь отправить JSONObject, который отправляется на 'onPostExecute()' обратно в класс ** 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()); 
     }  
    } 
} 
Смежные вопросы