2012-01-10 11 views
6

Antes de leer: utilicé librerías GSON descargables en este programa. http://webscripts.softpedia.com/script/Development-Scripts-js/Other-Libraries/Gson-71373.htmlAnálisis de cadenas JSON desde URL (servicio web RESTful) utilizando las bibliotecas GSON. Android

He estado tratando de analizar JSON desde hace bastante tiempo, pero cada vez que trato de obtener la cadena de la URL, el programa no "funciona". No falla ni se cierra ni recibe errores. Simplemente no hace el análisis. Mi programa está destinado a analizar desde http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo y tiene un botón para actualizar ejecutar el proceso de análisis de nuevo para que actualice la información. Si utilizo una cadena JSON codificada, el programa funciona perfectamente. Incluso coloco la cadena que se supone que se recupera de la URL; pero parece que no puedo obtenerlo directamente. Estoy usando las librerías GSON.

En el código, he proporcionado comentarios para explicar mi proceso de pensamiento. Tenga en cuenta que tengo 2 métodos diferentes que están tratando de usar la URL (pensé que tal vez la original estaba equivocada, así que traté de usar otra), esta era yo aferrándome a las pajas. Por favor, ayúdame. Gracias.

mi código:.

package com.android.testgson; 

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.URI; 
import java.net.URL; 

import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

import com.google.gson.Gson; 

public class GSONTestActivity extends Activity { 
    /** Called when the activity is first created. */ 

    //String test = ""; 

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

     TextView tv = (TextView)findViewById(R.id.textViewInfo); 
     syncButtonClickListener(); 

     runJSONParser(tv); 

    } 

    private void syncButtonClickListener() 
    { 

     Button syncButton = (Button)findViewById(R.id.buttonSync); 
     syncButton.setOnClickListener(new View.OnClickListener() 
     { 
      public void onClick(View v) 
      { 
       TextView tv = (TextView)findViewById(R.id.textViewInfo); 
       runJSONParser(tv); 
      } 
     }); 
    } 


    public InputStream getJSONData(String url){ 
     // create DefaultHttpClient 
     HttpClient httpClient = new DefaultHttpClient(); 
     URI uri; // for URL 
     InputStream data = null; // for URL's JSON 

     try { 
      uri = new URI(url); 
      HttpGet method = new HttpGet(uri); // Get URI 
      HttpResponse response = httpClient.execute(method); // Get response from method. 
      data = response.getEntity().getContent(); // Data = Content from the response URL. 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return data; 
    } 

    public void runJSONParser(TextView tv){ 
     try{ 
      Gson gson = new Gson(); 
      //Reader r = new InputStreamReader(getJSONData("http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo")); 
      /**I tried parsing the URL, but it didn't work. No error messages, just didn't parse.*/ 
      //Reader r = new InputStreamReader(getJSONData("android.resource://"+ getPackageName() + "/" + R.raw.yourparsable)); 
      /**I tried parsing from local JSON file. Didn't work. Again no errors. The program simply stalls. */ 

      //String testString = "{\"weatherObservation\":{\"clouds\":\"few clouds\",\"weatherCondition\":\"n/a\",\"observation\":\"LSZH 041320Z 24008KT 210V270 9999 FEW022 SCT030 BKN045 05/01 Q1024 NOSIG\",\"windDirection\":\"240\",\"ICAO\":\"LSZH\",\"elevation\":\"432\",\"countryCode\":\"CH\",\"lng\":\"8.516666666666667\",\"temperature\":\"5\",\"dewPoint\":\"1\",\"windSpeed\":\"08\",\"humidity\":\"75\",\"stationName\":\"Zurich-Kloten\",\"datetime\":\"2012-01-04 13:20:00\",\"lat\":\"47.46666666666667\",\"hectoPascAltimeter\":\"1024\"}}"; 
      /**If I parse this string. The parser works. It is the same exact string like in the URL.*/ 
      //String failString = "{\"status\":{\"message\":\"the hourly limit of 2000 credits demo has been exceeded. Please throttle your requests or use the commercial service.\",\"value\":19}}"; 
      /**Even if the url delivers this string (because the hourly limit would be reached), the string is still parsed correctly.*/ 
      String json = readUrl("http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo"); 
      /**At this point I tried a different means of accessing the URL but still I had the exact same problem*/ 

      Observation obs = gson.fromJson(json, Observation.class); 
      // "json" can be replaced with r, testString, failString to see all my previous results. 

      if (obs.getWeatherObservation()!=null) 
      { 
       tv.setText("Clouds - " + obs.getWeatherObservation().getClouds() 
         + "\nTemperature - " + obs.getWeatherObservation().getTemperature() 
         + "\nWind Speed - " + obs.getWeatherObservation().getWindSpeed() 
         + "\nHumidity - " + obs.getWeatherObservation().getHumidity()); 
      } 
      else if (obs.getStatus()!=null) 
      { 
       tv.setText("Message - " + obs.getStatus().getMessage() 
         + "\nValue - " + obs.getStatus().getValue()); 
      } 

     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 

    } 

    public static String readUrl(String urlString) throws Exception { 
     BufferedReader reader = null; 

     try{ 
      URL url = new URL(urlString); 
      reader = new BufferedReader(new InputStreamReader (url.openStream())); 
      StringBuffer buffer = new StringBuffer(); 
      int read; 
      char[]chars = new char[1024]; 
      while ((read = reader.read(chars)) != -1) 
       buffer.append(chars, 0, read); 

      return buffer.toString(); 
     } finally { 
      if (reader != null) 
       reader.close(); 
     } 

    } 
} 
+0

Podría publicar su 'Observation.java'? – curioustechizen

+0

¿Ha verificado que 'readURL' de hecho está devolviendo la cadena que espera? –

Respuesta

0

que he hecho el análisis de JSON utilizando el org.json *

http://www.json.org/java/index.html Docs en Android 4. http://developer.android.com/reference/org/json/package-summary.html (como ejemplo)

Puede descargar el jar desde aquí http://repo1.maven.org/maven2/org/json/json/20090211/json-20090211.jar

También consideraría ejecutar sus solicitudes http en un hilo diferente y solo luego volver a dibujar su interfaz de usuario. Lea sobre android.os.Handler también para ese propósito.

gracias

2

como Sergey, he encontrado que la biblioteca JSON incluido org.json.* en Android es mucho más simple de usar que GSON.

Por ejemplo, en su escenario, su código de análisis JSON se vería así.

String jsonData = readUrl("http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo"); 
JSONObject weatherJSONObject = new JSONObject(jsonData); 

try { 
    // Not sure the format of your data, but you would want something like this 
    String clouds = weatherJSONObject.getString("clouds"); 
} catch (JSONException e) { 
    e.printStackTrace(); 
} 

También se beneficiarían de AsyncTask o Thread. Nunca desea ejecutar operaciones de ejecución prolongada en el subproceso de la interfaz de usuario porque la interfaz de usuario parecerá que no responde y es lenta.

A continuación se muestra un ejemplo de cómo puede usar AsyncTask para lograr su objetivo. Lea más sobre esto here

private class FetchJSONDataTask extends AsyncTask<String, Void, JSONObject> { 

    // This gets executed on a background thread 
    protected JSONObject doInBackground(String... params) { 
     String urlString = params[0]; 
     String jsonData = readUrl(urlString); 
     JSONObject weatherJSONObject = new JSONObject(jsonData); 
     return weatherJSONObject; 
    } 

    // This gets executed on the UI thread 
    protected void onPostExecute(JSONObject json) { 
     //Your function that takes a json object and populates views 
     setUpViews(json); 
    } 
} 

Y para ejecutar su tarea, debe ejecutar este código en su actividad.

FetchJSONDataTask task = new FetchJSONDataTask(); 
task.execute(new String[] { "http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo" }); 

Nota: Este código no ha sido probado, pero esa debería ser la idea general.

0

respuesta JSON se gzipped normalmente, intente esto en su método getJSONData():

... ... 
uri = new URI(url); 
HttpGet method = new HttpGet(uri); // Get URI 
HttpResponse response = httpClient.execute(method); // Get response from method. 
InputStream in = response.getEntity().getContent(); 
GZIPInputStream gin = new GZIPInputStream(in); 
BufferedReader reader = new BufferedReader(new InputStreamReader(gin)); 
String line = null; 
while ((line = reader.readLine()) != null) { 
    jsonResponse.append(line); 
} 
reader.close(); 
... ... 
Cuestiones relacionadas