2013-08-08 13 views
6

Próbuję parsować niektóre dane JSON. Mój kod działał przez jakiś czas i nie jestem pewien, co zmieniłem, aby nagle złamać kod. Kiedy uruchamiam mój kod, nie otrzymuję żadnych błędów runtime ani ostrzeżeń. Tworzę nową AsyncTask i wykonuję to. Kiedy zadzwonię pod numer .get() w tym nowym zadaniu, debugger zatrzymuje się na tej linii i zajmuje więcej niż 30 minut. Nie mogłem pobrać debuggera lub podczas uruchamiania, aby ukończyć to zadanie.Android Parse JSON zatrzymany na zadanie get

JSON:

protected void setUp(Context context) { 
    _context = context; 
    getConfig(); 
} 

// get config file 
protected void getConfig() { 
    if (config != null) 
     return; 

    config = new Config(); 

    String url = configURL; 
    AsyncTask<String, Integer, JSONObject> jsonTask = new DownloadJSONTask() 
      .execute(url); 
    JSONObject configItem = null; 
    try { 
     configItem = jsonTask.get(); //debugger pauses here 
     if (configItem == null) 
      return; 
     config.configVersion = configItem.getString("field_configversion"); 
     config.currentAppVersion = configItem 
       .getString("field_currentappversion"); 
     config.getSupportURL = configItem.getString("field_getsupporturl"); 
     config.getCatalogURL = configItem.getString("field_getcatalogurl"); 
     config.getDataVersion = configItem.getString("field_dataversion"); 
     config.getDataUrl = configItem.getString("field_dataurl"); 
     config.getDataApiKey = configItem.getString("field_dataapikey"); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
     System.err.println("Download of config interrupted"); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
     System.err.println("Download of config failed to execute"); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 

    cacheStaticData(_context); 
} 

DownloadJSONTask.java

package com.example.simplegraph; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.content.Context; 
import android.os.AsyncTask; 

public class DownloadJSONTask extends AsyncTask<String, Integer, JSONObject> { 
private HttpClient client = new DefaultHttpClient(); 
private HttpGet request; 
private HttpResponse response; 

DownloadJSONTask() { 
    super(); 
} 

// tries to grab the data for a JSONObject 
@Override 
protected JSONObject doInBackground(String... urls) { 

    request = new HttpGet(urls[0]); 
    try { 
     response = client.execute(request); 
     HttpEntity entity = response.getEntity(); 
     if (entity != null) { 
      InputStream instream = entity.getContent(); 
      String result = convertStreamToString(instream); 
      JSONObject json = new JSONObject(result); 
      instream.close(); 
      return json; 
     } 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

// converts the InputStream to a string and add nl 
private String convertStreamToString(InputStream is) { 
    BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
    StringBuilder sb = new StringBuilder(); 
    String line = null; 
    try { 
     while ((line = br.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
    } catch (IOException ioe) { 
     ioe.printStackTrace(); 
    } finally { 
     try { 
      is.close(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
    return sb.toString(); 
} 
} 

I HomeActivity.java

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    new AddStringTask().execute(); 

} 

class AddStringTask extends AsyncTask<Void, String, Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 

     app = (EconApplication) getApplication(); 
     getApp().setUp(HomeActivity.this); 
     HomeActivity.this.setUpDrawer(); 
     return (null); 
    } 

    @Override 
    protected void onPostExecute(Void unused) { 
     setUpDataDisplay(); 
     setUpGraphRange(); 
     createTable(); 
     createGraph(-1); 
    } 
} 

PYTANIE: Dlaczego mój kod utknięcie na .get()?

+0

"utknąć" oznacza, który wynik logcat? – bofredo

+0

gdzie jest ta metoda 'get()' i co robi? – Raghunandan

+0

@Raghunandan get() jest w pierwszym zestawie kodu. Zaraz po próbie. I służy do uzyskania JSON. – buczek

Odpowiedz

1

AsyncTask.get() blokuje wątku rozmówcy. Zamiast tego użyj AsyncTask.execute().

public final Result get()

Dodano poziomu API 3

Waits jeśli to konieczne dla obliczeń do wykonania, a następnie pobiera jej wynik.

Zwraca Obliczony wynik.

Czerpiąc z

How do I return a boolean from AsyncTask?

Spróbuj poniżej

new DownloadJSONTask(ActivityName.this).execute(url); 

W swojej DownloadJSONTask

W construcotr

TheInterface listener; 
    public DownloadJSONTask(Context context) 
{ 

    listener = (TheInterface) context; 

} 

Interfejs

public interface TheInterface { 

    public void theMethod(ArrayList<String> result); // your result type 

    } 

W swojej doInbackground zwraca wynik. Zakładam jego ArrayList typu String. Zmień listę tablicową na odpowiadającą Twoim wymaganiom.

w twojej onPostExecute

if (listener != null) 
    { 
     listener.theMethod(result); // result is the ArrayList<String> 
     // result returned in doInbackground 
     // result of doInbackground computation is a parameter to onPostExecute 
    } 

w klasie aktywności zaimplementować interfejs

public class ActivityName implements DownloadJSONTask.TheInterface 

Następnie

@Override 
public void theMethod(ArrayList<String> result) { // change the type of result according yo your requirement 
// use the arraylist here 
} 

Edit: Alternatywna

Można zrobić s twój asynctask to wewnętrzna klasa twojej klasy aktywności. Wynik obliczenia doInbackground jest parametrem dla onPostExecute. Wynik zwrotu w doInbackground. Zaktualizuj ui w onPostExecute.

+0

Jeszcze raz dziękuję, jest to bardzo pomocne. – buczek

+0

@buczek jesteś mile widziany i cieszę się, że to pomaga. – Raghunandan

1

można znacznie uprościć wszystko przy użyciu biblioteki droidQuery:

$.getJSON("http://www.example.com", null, new Function() {//this will run using an AsyncTask, get the JSON, and return either a JSONObject or JSONArray on the UI Thread. 
    @Overrde 
    public void invoke($ droidQuery, Object... params) { 
     if (params[0] instanceof JSONObject) { //it's often ok just to assume a JSONObject, making your first line simply: JSONObject obj = (JSONObject) params[0]; 
      //JSONObject is returned 
      JSONObject json = (JSONObject) params[0]; 
      //to easily parse this Object, convert it to a map first: 
      Map<String, ?> map = $.map(json); 
      //then you can just make a call like this: 
      if (map.contains("field_currentappversion")) { 
       config.currentAppVersion = (String) map.get("field_currentappversion"); 
      } 
     } 
     else { 
      //JSONArray is returned 
      JSONArray json = (JSONArray) params[0]; 
      //if you got an array, you can easily convert it to an Object[] for parsing: 
      Object[] array = $.makeArray(json); 
     } 
    } 
}); 
+0

To nie rozwiązuje mojego problemu, zamiast tego sugerujesz, że używam innej biblioteki. – buczek