2013-08-08 8 views
6

Sto cercando di analizzare alcuni dati JSON. Il mio codice funzionava da un po 'e non sono sicuro di cosa ho modificato per interrompere improvvisamente il codice. Quando eseguo il mio codice non ricevo errori di runtime o avvisi. Creo un nuovo AsyncTask ed eseguo questo. Quando chiamo .get() in questa nuova attività, il debugger si blocca su questa riga e impiega più di 30 minuti. Non sono stato in grado di ottenere il debugger o durante l'esecuzione per completare questa attività.Android Parse JSON bloccato su get task

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

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

DOMANDA: Perché il mio codice di rimanere bloccati su .get()?

+0

"bloccato" indica quale uscita logcat? – bofredo

+0

dov'è questo metodo 'get()' e cosa fa? – Raghunandan

+0

@Raghunandan get() è nel primo set di codice. Subito dopo il tentativo. Ed è usato per ottenere il JSON. – buczek

risposta

1

AsyncTask.get() blocca il thread chiamante. Utilizzare invece AsyncTask.execute().

public final Result get()

aggiunte a livello API 3

Waits se necessario per il calcolo di completare, e quindi recupera suo risultato.

Restituisce il risultato calcolato.

Attingendo

How do I return a boolean from AsyncTask?

Prova il seguito

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

Nella tua DownloadJSONTask

Nel construcotr

TheInterface listener; 
    public DownloadJSONTask(Context context) 
{ 

    listener = (TheInterface) context; 

} 

interfaccia

public interface TheInterface { 

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

    } 

Nella tua doInbackground restituire il risultato. Sto assumendo il suo ArrayList di tipo String. Cambia l'arraylist in base alle tue esigenze.

Nella tua 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 
    } 

Nella classe di attività implementano l'interfaccia

public class ActivityName implements DownloadJSONTask.TheInterface 

Poi

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

Edit: Alternative

Si può fare s il tuo asynctask una classe interna della tua classe di attività. Il risultato sul calcolo doInbackground è un parametro su onPostExecute. Restituisce il risultato in doInbackground. Aggiorna ui in onPostExecute.

+0

Grazie ancora, questo è molto utile. – buczek

+0

@buczek sei il benvenuto e felice che ti aiuti. – Raghunandan

1

È possibile semplificare notevolmente tutto utilizzando la libreria 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

Questo non risolve il mio problema, invece stai suggerendo di usare qualche altra libreria. – buczek