2012-01-10 11 views
6

Trước khi đọc: Tôi đã sử dụng thư viện GSON có thể tải xuống trong chương trình này. http://webscripts.softpedia.com/script/Development-Scripts-js/Other-Libraries/Gson-71373.htmlPhân tích chuỗi JSON từ URL (RESTful webservice) bằng cách sử dụng thư viện GSON. Android

Tôi đã cố gắng phân tích cú pháp JSON trong một thời gian ngắn nhưng mỗi lần tôi cố gắng lấy chuỗi từ URL chương trình không "hoạt động". Nó không thất bại hoặc đóng cửa hoặc nhận được lỗi. Nó không làm phân tích cú pháp. Chương trình của tôi có nghĩa là phân tích cú pháp từ http://api.geonames.org/weatherIcaoJSON?ICAO=LSZH&username=demo và có nút để cập nhật chạy quá trình phân tích cú pháp một lần nữa để nó sẽ làm mới thông tin. Nếu tôi sử dụng chuỗi JSON được mã hóa cứng, chương trình sẽ hoạt động hoàn hảo. Tôi thậm chí đặt trong chuỗi đó là vụ phải được lấy từ URL; nhưng tôi dường như không thể lấy nó trực tiếp. Tôi đang sử dụng thư viện GSON.

Trong mã, tôi đã cung cấp các nhận xét để giải thích quy trình suy nghĩ của tôi. Lưu ý rằng tôi có 2 phương pháp khác nhau đang cố gắng sử dụng URL (tôi nghĩ rằng có lẽ bản gốc là sai vì vậy tôi đã cố gắng sử dụng một cái khác), đây là tôi nắm lấy ống hút. Hãy giúp tôi ra. Cảm ơn bạn.

Mã của tôi:.

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

Bạn có thể đăng 'của bạn Observation.java'? – curioustechizen

+0

Bạn đã xác minh rằng 'readURL' là không trả về chuỗi bạn mong đợi? –

Trả lời

0

tôi đã thực hiện các phân tích cú pháp JSON sử dụng org.json *

http://www.json.org/java/index.html Documents trong Android 4. http://developer.android.com/reference/org/json/package-summary.html (như là một ví dụ)

Bạn có thể tải xuống bình từ đây http://repo1.maven.org/maven2/org/json/json/20090211/json-20090211.jar

Tôi cũng sẽ xem xét chạy ning yêu cầu http của bạn trong một chủ đề khác nhau và chỉ sau đó vẽ lại giao diện người dùng của bạn. Đọc về android.os.Handler vì mục đích đó.

nhờ

2

Giống như Sergey, tôi đã phát hiện ra rằng json thư viện bao gồm org.json.* trên Android là xa đơn giản để sử dụng hơn GSON.

Ví dụ: trong trường hợp của bạn - mã phân tích cú pháp JSON của bạn sẽ trông như thế này.

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ạn cũng sẽ được hưởng lợi từ AsyncTask hoặc Thread. Bạn không bao giờ muốn chạy các hoạt động chạy dài trên chuỗi giao diện người dùng vì giao diện người dùng sẽ xuất hiện không phản hồi và chậm chạp.

Dưới đây là ví dụ về cách bạn có thể sử dụng AsyncTask để đạt được mục tiêu của mình. Đọc thêm về nó 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); 
    } 
} 

Và để thực hiện nhiệm vụ, bạn nên chạy mã này trong hoạt động của mình.

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

Lưu ý: Mã này chưa được kiểm tra, nhưng đó phải là ý tưởng chung.

0

JSON phản ứng thường gzip, hãy thử này trong phương pháp của bạn 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(); 
... ...