尝试在空对象引用上调用虚拟方法' void com.google.android.gms.maps.GoogleMap.moveCamera

时间:2017-04-12 08:46:43

标签: android

我是初学者,我想开发一个谷歌地图应用程序,我可以在其中搜索并从自动完成搜索中选择一个地方,但是当我点击任何地方然后我的应用程序崩溃并在logcat中显示此错误任何人帮助我,

MainActivity Code

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        switch(downloadType){
            case PLACES:
                // Creating ParserTask for parsing Google Places
                placesParserTask = new ParserTask(PLACES);

                // Start parsing google places json data
                // This causes to execute doInBackground() of ParserTask class
                placesParserTask.execute(result);

                break;

            case PLACES_DETAILS :
                // Creating ParserTask for parsing Google Places
                placeDetailsParserTask = new ParserTask(PLACES_DETAILS);

                // Starting Parsing the JSON string
                // This causes to execute doInBackground() of ParserTask class
                placeDetailsParserTask.execute(result);
        }
    }
}

/** A class to parse the Google Places in JSON format */
private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String,String>>> implements OnMapReadyCallback {

    int parserType = 0;

    public ParserTask(int type){
        this.parserType = type;
    }

    @Override
    protected List<HashMap<String, String>> doInBackground(String... jsonData) {

        JSONObject jObject;
        List<HashMap<String, String>> list = null;

        try{
            jObject = new JSONObject(jsonData[0]);

            switch(parserType){
                case PLACES :
                    PlaceJSONParser placeJsonParser = new PlaceJSONParser();
                    // Getting the parsed data as a List construct
                    list = placeJsonParser.parse(jObject);
                    break;
                case PLACES_DETAILS :
                    PlaceDetailsJSONParser placeDetailsJsonParser = new PlaceDetailsJSONParser();
                    // Getting the parsed data as a List construct
                    list = placeDetailsJsonParser.parse(jObject);
            }

        }catch(Exception e){
            Log.d("Exception",e.toString());
        }
        return list;
    }

    @Override
    protected void onPostExecute(List<HashMap<String, String>> result) {

        switch(parserType){
            case PLACES :
                String[] from = new String[] { "description"};
                int[] to = new int[] { android.R.id.text1 };

                // Creating a SimpleAdapter for the AutoCompleteTextView
                SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, from, to);

                // Setting the adapter
                atvPlaces.setAdapter(adapter);
                break;
            case PLACES_DETAILS :
                HashMap<String, String> hm = result.get(0);

                // Getting latitude from the parsed data
                double latitude = Double.parseDouble(hm.get("lat"));

                // Getting longitude from the parsed data
                double longitude = Double.parseDouble(hm.get("lng"));

                // Getting reference to the SupportMapFragment of the activity_main.xml
                SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

                // Getting GoogleMap from SupportMapFragment
                fm.getMapAsync(this);

                LatLng point = new LatLng(latitude, longitude);

                CameraUpdate cameraPosition = CameraUpdateFactory.newLatLng(point);
                CameraUpdate cameraZoom = CameraUpdateFactory.zoomBy(5);

                // Showing the user input location in the Google Map
               mMap.moveCamera(cameraPosition);
             mMap.animateCamera(cameraZoom);

                MarkerOptions options = new MarkerOptions();
                options.position(point);
                options.title("Position");
                options.snippet("Latitude:"+latitude+",Longitude:"+longitude);

                // Adding the marker in the Google Map
              mMap.addMarker(options);

                break;
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap=googleMap;
    }
}

LogCat

 FATAL EXCEPTION: main
              Process: com.example.awais.mapapp1, PID: 13727
              java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.moveCamera(com.google.android.gms.maps.CameraUpdate)' on a null object reference 
              at com.example.awais.mapapp1.MainActivity$ParserTask.onPostExecute(MainActivity.java:332)
              at com.example.awais.mapapp1.MainActivity$ParserTask.onPostExecute(MainActivity.java:262)
               at android.os.AsyncTask.finish(AsyncTask.java:664)
               at android.os.AsyncTask.-wrap1(AsyncTask.java)
               at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:681)
               at android.os.Handler.dispatchMessage(Handler.java:102)
               at android.os.Looper.loop(Looper.java:148)
               at android.app.ActivityThread.main(ActivityThread.java:5452)
               at java.lang.reflect.Method.invoke(Native Method)
               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:762)
               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
04-12 13:40:03.173 13727-13733/com.example.awais.mapapp1 W/art: Suspending all threads took: 7.995ms

2 个答案:

答案 0 :(得分:0)

您的mMap在初始化之前正在使用。 试试这个。

if(mMap!=null){
     mMap.moveCamera(cameraPosition);
                 mMap.animateCamera(cameraZoom);
    }

答案 1 :(得分:0)

所以,让我们在这里添加一些细节,以便您更好地理解。

您的问题是由于在AsyncTask执行和完成之前地图尚未就绪这一事实造成的,这意味着在AsyncTask的{​​{1}}方法中onPostExecutemMap

那该怎么办?那取决于你想要什么。

  1. 如果您真的需要null中的地图,确保地图在那里的最简单方法是在地图准备好后onPostExecute开始AsyncTask }})。

  2. 如果您不关心地图更新,可以在onMapReady进行空检查。

  3. 现在让我们提供一些代码:

    第一种情况:

    onPostExecute

    如果您必须先完成第一个@Override public void onMapReady(GoogleMap googleMap) { mMap=googleMap; new DownloadTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); //This is the correct way to start an async task, //Also this is your first async task that I assume you execute for which you have the first onPostExecute. //The rest of the code should be ok with you. } ,则可以存储活动中的变量,并在地图准备好或任务完成时进行检查。像这样的东西

    onPostExecute