2012-01-10 10 views
6

Przed rozpoczęciem czytania: W tym programie korzystałem z pobieralnych bibliotek GSON. http://webscripts.softpedia.com/script/Development-Scripts-js/Other-Libraries/Gson-71373.htmlAnalizowanie łańcucha JSON z adresu URL (usługa sieciowa RESTful) przy użyciu bibliotek GSON. Android

Próbuję parsować JSON od dłuższego czasu, ale za każdym razem, gdy próbuję uzyskać ciąg z adresu URL program nie "działa". Nie zawiedzie, nie zamknie się ani nie dostanie błędów. Po prostu nie parsuje. Mój program jest przeznaczony do analizowania od http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo i ma przycisk do aktualizacji, aby ponownie uruchomić proces parsowania, aby odświeżył informacje. Jeśli użyję zakodowanego ciągi JSON, program działa idealnie. Wprowadziłem nawet ciąg, który powinien być pobrany z adresu URL; ale wydaje mi się, że nie jestem w stanie uzyskać tego bezpośrednio. Korzystam z bibliotek GSON.

W kodzie podano komentarze do wyjaśnienia mojego procesu myślowego. Zauważ, że mam 2 różne metody, które próbują użyć adresu URL (myślałem, że być może oryginalny był błędny, więc próbowałem użyć innego), to byłem ja chwytając się słomek. Proszę pomóż mi. Dziękuję Ci.

mój kod.

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

mógłbyś zamieścić swoje 'Observation.java'? – curioustechizen

+0

Czy zweryfikowałeś, że 'readURL' zwraca infekcję, której oczekujesz? –

Odpowiedz

0

Zrobiłem parsowania json używając org.json *

http://www.json.org/java/index.html Docs w Androidzie 4. http://developer.android.com/reference/org/json/package-summary.html (jako przykład)

Możesz pobrać słoik stąd http://repo1.maven.org/maven2/org/json/json/20090211/json-20090211.jar

Chciałbym również rozważyć uruchomienie ning swoich żądań http w innym wątku, a dopiero potem przerysować twój interfejs. Przeczytaj o android.os.Handler również w tym celu.

dzięki

2

jak Siergiej, Znalazłem, że zawarte json biblioteka org.json.* na Androida jest znacznie prostszy w obsłudze niż GSON.

Na przykład w twoim scenariuszu - Twój kod parsujący JSON wyglądałby tak.

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

będzie również skorzystać z AsyncTask lub Thread. Nigdy nie chcesz uruchamiać długich operacji w wątku interfejsu użytkownika, ponieważ interfejs użytkownika będzie wyglądał na nie odpowiada i będzie słaby. Poniżej przedstawiono przykład użycia AsyncTask do osiągnięcia celu. Czytaj więcej na ten temat 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); 
    } 
} 

I aby wykonać swoje zadanie, należy uruchomić ten kod w swojej działalności.

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

Uwaga: ten kod nie został przetestowany, ale taki powinien być ogólny pomysł.

0

odpowiedź JSON jest zazwyczaj skompresowane, spróbuj tego w metodzie swojej 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(); 
... ... 
Powiązane problemy