在后台空指针异常中解析 JSON



我正在尝试从特定网址获取我的 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。

最新更新