我正在尝试从特定网址获取我的 JSON 对象,当我点击 .execute();我得到指向我的 JSON 数组的空指针异常。问题应该在哪里?我试图将 .execute() 方法放在其他地方,但仍然不起作用。而且我确信网址是 100% 正确的
我的 JSONParser 类:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
我的 JSON:
{
"current_ts": 1425907330,
"username": "guri",
"events": [
{
"id": 16591481,
"ts": 1425907325,
"lat": 48.17,
"lon": 17.13,
"likes": 5,
"text": "Poziar na hlavnej stanici",
"tags": "#poziar #stanica #hori",
"img": "2002-06-19.jpg"
},
{
"id": 47067411,
"ts": 1425907100,
"lat": 48.81,
"lon": 17.22,
"likes": 0,
"text": "V Bille je velky vypredaj",
"tags": [
{
"tag1": "#akcia",
"tag2": "#akcia"
}
],
"img": "DSC04934.jpg"
}
]
}
这是我的代码:
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
double lon = 0;
double lat = 0;
private static final String TAG_EVENT = "events";
private static final String TAG_LAT = "lat";
private static final String TAG_LON = "lon";
private static final String TAG_TEXT = "text";
JSONArray event = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//requestWindowFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_main);
setUpMapIfNeeded();
//new JSONParse().execute();
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
// Setting Dialog Title
alertDialog.setTitle("GPS settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
private void setUpMapIfNeeded() {
LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
/*if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
showSettingsAlert();
}
else{*/
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Showing status
if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
}else { // Google Play Services are available
// Getting reference to the SupportMapFragment of activity_menu.xml
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
// Getting mMap object from the fragment
mMap = fm.getMap();
// Enabling MyLocation Layer of Google Map
mMap.setMyLocationEnabled(true);
// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
/*if(networkEnabled){*/
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location!=null){
lon = location.getLongitude();
lat = location.getLatitude();
LatLng latLng = new LatLng(lat, lon);
// Showing the current location in Google Map
//mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
//mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
/*}*/
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location
location = locationManager.getLastKnownLocation(provider);
if(location!=null){
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, 2000, 0, this);
/*}*/}
}
@Override
public void onLocationChanged(Location location) {
/*double latitude = location.getLatitude();
// Getting longitude of the current location
double longitude = location.getLongitude();
// Creating a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);
// Showing the current location in Google Map
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));*/
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_menu, menu);
super.onCreateOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
// Handle action buttons
switch(item.getItemId()) {
case R.id.something:
// create intent to perform web search for this planet
/*Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
//intent.putExtra(SearchManager.QUERY, getSupportActionBar().getTitle());
// catch event that there's no activity to handle intent
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Toast.makeText(this, "app not available", Toast.LENGTH_LONG).show();
}*/
new JSONParse().execute();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
//uid = (TextView)findViewById(R.id.uid);
//name1 = (TextView)findViewById(R.id.name);
//email1 = (TextView)findViewById(R.id.email);
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected JSONObject doInBackground(String... args) {
JSONParser jParser = new JSONParser();
// Getting JSON from URL
return jParser.getJSONFromUrl("http://guri.sk/mapped/mapped.json");
}
@Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
try {
// Getting JSON Array
event = json.getJSONArray(TAG_EVENT);
JSONObject c = event.getJSONObject(3);
// Storing JSON item in a Variable
double lat2 = c.getDouble(TAG_LAT);
double lon2 = c.getDouble(TAG_LON);
String text = c.getString(TAG_TEXT);
//Set JSON Data in TextView
//uid.setText(id);
//name1.setText(name);
//email1.setText(email);
mMap.addMarker(new MarkerOptions().position(new LatLng(lat2, lon2)).title(text));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
我的日志猫:
Process: com.digitale.mapped, PID: 23552
java.lang.NullPointerException
at com.digitale.mapped.MainActivity$JSONParse.onPostExecute(MainActivity.java:231)
at com.digitale.mapped.MainActivity$JSONParse.onPostExecute(MainActivity.java:206)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:212)
at android.app.ActivityThread.main(ActivityThread.java:5135)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
at dalvik.system.NativeStart.main(Native Method)
第 231 行是 event = json.getJSONArray(TAG_EVENT);
应该是
sb.append(line).append("n");
你有
sb.append(line).append("n");
jParser.getJSONFromUrl("http://guri.sk/mapped/mapped.json")返回空值。所以你在 onPostExecute() 中得到了一个空引用。所以当你调用
event = json.getJSONArray(TAG_EVENT);//这里 json 是一个空引用
这就是您的NPE的原因
错误在方法中查找onPostExecute()
我测试了您用来获取 JSONObject 的网址。URL 返回 JSONArray 中仅有的 2 个对象,因此您无法获取索引 3。
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
try {
// Getting JSON Array
event = json.getJSONArray(TAG_EVENT);
**JSONObject c = event.getJSONObject(3);**//The index is 3, It should be less than 2
// Storing JSON item in a Variable
double lat2 = c.getDouble(TAG_LAT);
double lon2 = c.getDouble(TAG_LON);
String text = c.getString(TAG_TEXT);
//Set JSON Data in TextView
//uid.setText(id);
//name1.setText(name);
//email1.setText(email);
mMap.addMarker(new MarkerOptions().position(new LatLng(lat2, lon2)).title(text));
} catch (JSONException e) {
e.printStackTrace();
}
}
AsyncTask 包装在如下所示的函数中:
private void parseJSON()
{
new AsyncTask<String, String, JSONObject>(){
// Your code here...
}.execute();
}
或者,将 AsyncTask 保存到一个变量并对其调用 execute。