状态变量返回nullPointerException(Android)

时间:2015-04-29 12:02:33

标签: java android variables nullpointerexception status

我一直在关注一个教程(http://www.androidhive.info/2012/08/android-working-with-google-places-and-maps-tutorial/),以便将列表视图显示在距离您所在位置最近的餐馆,方圆5公里。

但是我不断收到错误,在我的Runnable中它说状态变量为null。我真的不明白为什么会出现这个错误。你们能给我一个简短的解释并帮助找到解决方案吗?

PlacesList.java

public class PlacesList implements Serializable {

    public String status;
    public List<Place> results;

}

DisplayLocations.java

public class DisplayLocations extends Activity {

    boolean isInternetPresent = false;

    ConnectionDetector cd;
    GooglePlaces googlePlaces;
    PlacesList nearPlaces;
    GPSTracker gps;

    Button shownOnMap;
    ProgressDialog pDialog;

    ListView lv;

    ArrayList<HashMap<String, String>> placesListItems = new ArrayList<HashMap<String, String>>();

    public static String KEY_REFERENCE = "reference";
    public static String KEY_NAME = "name";
    public static String KEY_VICINITY = "vicinity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_locations);

        cd = new ConnectionDetector(getApplicationContext());

        isInternetPresent = cd.isConnectingToInternet();
        if(!isInternetPresent){
            Toast.makeText(getApplicationContext(), "Get a working connection", Toast.LENGTH_SHORT).show();
            return;
        }

        gps = new GPSTracker(DisplayLocations.this);

        if(gps.canGetLocation()){

        }else{
            gps.showSettingsAlert();
        }

        lv = (ListView)findViewById(R.id.list);
        shownOnMap = (Button)findViewById(R.id.btn_show_map);

        new LoadPlaces().execute();

        shownOnMap.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                Intent i = new Intent(getApplicationContext(), PlacesMapActivity.class);
                i.putExtra("user_latitude", Double.toString(gps.getLatitude()));
                i.putExtra("user_longitude", Double.toString(gps.getLongitude()));
                i.putExtra("near_places", nearPlaces);
                startActivity(i);
                */
            }
        });

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String reference = ((TextView) findViewById(R.id.reference)).getText().toString();
                /*
                Intent in = new Intent(getApplicationContext(), SingePlaceActivity.class);
                in.putExtra(KEY_REFERENCE, reference);
                startActivity(in);
                */
            }
        });
    }


    class LoadPlaces extends AsyncTask<String, String, String>{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(DisplayLocations.this);
            pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading Places..."));
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        @Override
        protected String doInBackground(String... params) {
            googlePlaces = new GooglePlaces();

            try{
                String types = "cafe|restaurant";
                double radius = 5000;
                nearPlaces = googlePlaces.search(gps.getLatitude(), gps.getLongitude(), radius, types);

            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String file_url) {
            pDialog.dismiss();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String status = nearPlaces.status;

                    if (status.equals("OK")){
                        if(nearPlaces.results != null){
                            for (Place p : nearPlaces.results){
                                HashMap<String, String> map = new HashMap<String, String>();
                                map.put(KEY_REFERENCE, p.reference);
                                map.put(KEY_NAME, p.name);
                                placesListItems.add(map);
                            }
                            ListAdapter adapter = new SimpleAdapter(DisplayLocations.this, placesListItems, R.layout.location_listview_item,
                                    new String[]{KEY_REFERENCE, KEY_NAME}, new int[]{R.id.reference, R.id.name});
                            lv.setAdapter(adapter);
                        }
                    }
                    else if(status.equals("ZERO_RESULTS")){
                        // Zero results found
                        Toast.makeText(getApplicationContext(), "No Results", Toast.LENGTH_SHORT);
                    }
                    else if(status.equals("UNKNOWN_ERROR"))
                    {
                        Toast.makeText(getApplicationContext(), "Unknown error", Toast.LENGTH_SHORT);
                    }
                    else if(status.equals("OVER_QUERY_LIMIT"))
                    {
                        Toast.makeText(getApplicationContext(), "Query limit reached !", Toast.LENGTH_SHORT);
                    }
                    else if(status.equals("REQUEST_DENIED"))
                    {
                        Toast.makeText(getApplicationContext(), "Request denied", Toast.LENGTH_SHORT);
                    }
                    else if(status.equals("INVALID_REQUEST"))
                    {
                        Toast.makeText(getApplicationContext(), "Invalid request", Toast.LENGTH_SHORT);
                    }
                    else
                    {
                        Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT);
                    }
                }
            });
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_display_locations, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

GooglePlaces.java

public class GooglePlaces {

    private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    private final String API_KEY = "AIzaSyCxY1X7hC7SOab7V3GbWd1u42fGThgYOhg";

    //GooglePlaces search URL
    private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
    private static final String PLACES_TEXT_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
    private static final String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json?";

    private double mLatitiude;
    private double mLongitude;
    private double mRadius;

    public PlacesList search(double latitude, double longitude, double radius, String types) throws Exception{
            this.mLatitiude = latitude;
            this.mLongitude = longitude;
            this.mRadius = radius;

            try {
                HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
                HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
                request.getUrl().put("key", API_KEY);
                request.getUrl().put("location", mLatitiude + "," + mLongitude);
                request.getUrl().put("radius", mRadius); // in meters
                request.getUrl().put("sensor", "false");
                if (types != null)
                    request.getUrl().put("types", types);

                PlacesList list = request.execute().parseAs(PlacesList.class);
                // Check log cat for places response status
                Log.d("Places Status", "" + list.status);
                return list;

            } catch (HttpResponseException e) {
                Log.e("Error:", e.getMessage());
                return null;
            }

    }

    public PlaceDetails getPlaceDetails(String reference) throws Exception{
        try{
            HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
            HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_DETAILS_URL));
            request.getUrl().put("reference", reference);
            request.getUrl().put("key", API_KEY);
            request.getUrl().put("sensor",false);

            PlaceDetails place = request.execute().parseAs(PlaceDetails.class);
            return place;

        }catch (HttpResponseException e){
            throw e;
        }
    }

    public static HttpRequestFactory createRequestFactory(final HttpTransport transport){
        return transport.createRequestFactory(new HttpRequestInitializer() {
            @Override
            public void initialize(HttpRequest request) throws IOException {
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.setUserAgent("Application Test");
                request.setHeaders(httpHeaders);
                    JsonObjectParser parser = new JsonObjectParser(new JsonFactory() {
                        @Override
                        public JsonParser createJsonParser(InputStream in) throws IOException {
                            return null;
                        }

                        @Override
                        public JsonParser createJsonParser(InputStream in, Charset charset) throws IOException {
                            return null;
                        }

                        @Override
                        public JsonParser createJsonParser(String value) throws IOException {
                            return null;
                        }

                        @Override
                        public JsonParser createJsonParser(Reader reader) throws IOException {
                            return null;
                        }

                        @Override
                        public JsonGenerator createJsonGenerator(OutputStream out, Charset enc) throws IOException {
                            return null;
                        }

                        @Override
                        public JsonGenerator createJsonGenerator(Writer writer) throws IOException {
                            return null;
                        }
                    });
                    request.setParser(parser);
            }

        });
    }
}

DisplayLocations.java的第132行是:

String status = nearPlaces.status;

这是堆栈跟踪:

 java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.example.dell.exampleapplication.PlacesList.status' on a null object reference
        at com.example.dell.exampleapplication.DisplayLocations$LoadPlaces$1.run(DisplayLocations.java:132)
        at android.app.Activity.runOnUiThread(Activity.java:5517)
        at com.example.dell.exampleapplication.DisplayLocations$LoadPlaces.onPostExecute(DisplayLocations.java:129)
        at com.example.dell.exampleapplication.DisplayLocations$LoadPlaces.onPostExecute(DisplayLocations.java:98)
        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:145)
        at android.app.ActivityThread.main(ActivityThread.java:5834)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)

任何帮助和解释都将不胜感激。

谢谢,祝你有愉快的一天。

2 个答案:

答案 0 :(得分:0)

编辑:

在doInBackGround中

nearPlaces.status = ...(状态:可能来自GooglePlaces)

然后你可以这样做: String status = nearPlaces.status;在onPostExecute

答案 1 :(得分:0)

添加行

    @Override
protected String doInBackground(String... params) {
    googlePlaces = new GooglePlaces();

    try{
        String types = "cafe|restaurant";
        double radius = 5000;
        nearPlaces = googlePlaces.search(gps.getLatitude(), gps.getLongitude(), radius, types);
        nearPlaces.status = "OK"; //Add this line for testing, your code should work now, because status is not NULL anymore. 

    }catch (Exception e){
        e.printStackTrace();
    }
    return null;
}