我收到此错误,尝试使用ListView构建JSON解析器。 我尝试使用另一个JSON源代码,它可以工作,但是这个链接崩溃了: http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
我喜欢一些帮助:D
错误:
05-21 20:53:32.871 2509-2606/com.ikeres.app.professorearthquake W/System.err: org.json.JSONException: End of input at character 0 of
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONTokener.nextValue(JSONTokener.java:97)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONObject.<init>(JSONObject.java:156)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at org.json.JSONObject.<init>(JSONObject.java:173)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity.ParseJSON(MainActivity.java:102)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity.access$200(MainActivity.java:19)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity$GetTerremotos.doInBackground(Mai nActivity.java:70)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at com.ikeres.app.professorearthquake.MainActivity$GetTerremotos.doInBackground(Mai nActivity.java:44)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
05-21 20:53:32.872 2509-2606/com.ikeres.app.professorearthquake W/System.err: at java.lang.Thread.run(Thread.java:818)
以下是MainActivity:
public class MainActivity extends ListActivity {
// URL to get contacts JSON
private static String url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson";
// JSON Node names
private static final String TAG_FEATURES = "features";
private static final String TAG_PROPERTIES = "properties";
private static final String TAG_LUGAR = "lugar";
private static final String TAG_MAGNITUD = "magnitud";
private static final String TAG_HORA = "hora";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling async task to get json
new GetTerremotos().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetTerremotos extends AsyncTask<Void, Void, Void> {
// Hashmap for ListView
ArrayList<HashMap<String, String>> terremotostList;
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
WebRequest webreq = new WebRequest();
// Making a request to url and getting response
String jsonStr = webreq.makeWebServiceCall(url, WebRequest.GET);
Log.d("Response: ", "> " + jsonStr);
terremotostList = ParseJSON(jsonStr);
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, terremotostList,
R.layout.list_item, new String[]{TAG_LUGAR, TAG_MAGNITUD,
TAG_HORA}, new int[]{R.id.name,
R.id.email, R.id.mobile});
setListAdapter(adapter);
}
}
private ArrayList<HashMap<String, String>> ParseJSON(String json) {
if (json != null) {
try {
// Hashmap for ListView
ArrayList<HashMap<String, String>> studentList = new ArrayList<HashMap<String, String>>();
JSONObject jsonObj = new JSONObject(json);
// Getting JSON Array node
JSONArray terremotos = jsonObj.getJSONArray(TAG_FEATURES);
// looping through All HeartQuakes
for (int i = 0; i < terremotos.length(); i++) {
JSONObject c = terremotos.getJSONObject(i);
// Properties node is JSON Object
JSONObject properties = c.getJSONObject(TAG_PROPERTIES);
String lugar = properties.getString(TAG_LUGAR);
String magnitud = properties.getString(TAG_MAGNITUD);
String hora = properties.getString(TAG_HORA);
// tmp hashmap for single hq
HashMap<String, String> oterremoto = new HashMap<String, String>();
// adding each child node to HashMap key => value
oterremoto.put(TAG_LUGAR, lugar);
oterremoto.put(TAG_MAGNITUD, magnitud);
oterremoto.put(TAG_HORA, hora);
// adding student to hq list
studentList.add(oterremoto);
}
return studentList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
return null;
}
}
}
WebRequest类:
public class WebRequest {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
//Constructor with no parameter
public WebRequest() {
}
/**
* Making web service call
*
* @url - url to make request
* @requestmethod - http request method
*/
public String makeWebServiceCall(String url, int requestmethod) {
return this.makeWebServiceCall(url, requestmethod, null);
}
/**
* Making service call
*
* @url - url to make request
* @requestmethod - http request method
* @params - http request params
*/
public String makeWebServiceCall(String urladdress, int requestmethod,
HashMap<String, String> params) {
URL url;
String response = "";
try {
url = new URL(urladdress);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setDoInput(true);
conn.setDoOutput(true);
if (requestmethod == POST) {
conn.setRequestMethod("POST");
} else if (requestmethod == GET) {
conn.setRequestMethod("GET");
}
if (params != null) {
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
writer.write(result.toString());
writer.flush();
writer.close();
os.close();
}
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
} else {
response = "";
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
答案 0 :(得分:0)
解析json时需要检查字段是否存在。您的代码在此行失败:
String lugar = properties.getString(TAG_LUGAR);
因为返回的json中没有这样的字段lugar
。所以这一行引发了一个异常,这个代码被捕获了:
catch (JSONException e) {
e.printStackTrace();
return null;
}
并返回NULL
。然后,您正在创建一个适配器并传递一个空对象:
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, terremotostList,
R.layout.list_item, new String[]{TAG_LUGAR, TAG_MAGNITUD,
TAG_HORA}, new int[]{R.id.name,
R.id.email, R.id.mobile});
(terremotostList
为空)
最后,您的适配器无法尝试访问列表中的getCount
方法,该方法为null。
如何解决这个问题?您应该在获取其值之前检查字段是否存在:
String lugar = properties.has(TAG_LUGAR) ? properties.getString(TAG_LUGAR) : null;
或只使用optString
方法,如果字段不存在则不会抛出异常:
String lugar = properties.optString(TAG_LUGAR);
答案 1 :(得分:0)
终于明白了。从WebRequest
类中删除以下行:
conn.setDoInput(true);
conn.setDoOutput(true);
在conn.setRequestMethod("GET");
之后添加以下内容:
conn.connect();
现在,您从JSON
中获得API
。之后你的应用程序将不会显示任何内容。那是因为你的标签都是西班牙语,而API
是英文的,所以改变:
private static final String TAG_LUGAR = "lugar";
private static final String TAG_MAGNITUD = "magnitud";
private static final String TAG_HORA = "hora";
为:
private static final String TAG_LUGAR = "place";
private static final String TAG_MAGNITUD = "mag";
private static final String TAG_HORA = "time";
在这些变化之后它会起作用。