我正在尝试在我的安卓应用程序中向谷歌地图添加一个标记。但是我在运行应用程序时收到空点异常。我看不出我的代码可能在哪里出错。
这是我使用过的代码
GoogleMap googleMap = null;
MapFragment fm = (MapFragment) (activity.getFragmentManager())
.findFragmentById(R.id.map);
googleMap = fm.getMap();
googleMap.addMarker(new MarkerOptions()
.position(new LatLng(7.421226f,80.401264f))
.title("Hello world"));
日志猫
12-31 16:51:54.667: E/AndroidRuntime(10191): FATAL EXCEPTION: main
12-31 16:51:54.667: E/AndroidRuntime(10191): java.lang.NullPointerException
12-31 16:51:54.667: E/AndroidRuntime(10191): at com.fortuna.cinemalk.adapter.ViewPageAdapter.instantiateItem(ViewPageAdapter.java:201)
12-31 16:51:54.667: E/AndroidRuntime(10191): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:829)
12-31 16:51:54.667: E/AndroidRuntime(10191): at android.support.v4.view.ViewPager.populate(ViewPager.java:979)
12-31 16:51:54.667: E/AndroidRuntime(10191): at android.support.v4.view.ViewPager.populate(ViewPager.java:911)
12-31 16:51:54.667: E/AndroidRuntime(10191): at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:440)
12-31 16:51:54.667: E/AndroidRuntime(10191): at com.fortuna.cinemalk.TheaterDetailFragment$BackGround.onPostExecute(TheaterDetailFragment.java:148)
12-31 16:51:54.667: E/AndroidRuntime(10191): at com.fortuna.cinemalk.TheaterDetailFragment$BackGround.onPostExecute(TheaterDetailFragment.java:1)
1) 片段可能为空。
除非在布局中定义了地图片段,否则您无法在 onCreate
中找到它。(如果是这种情况,请告诉我,我会更新答案。
2)片段尚未加载地图。
这是更有可能的情况。您可以拥有 MapFragment
的实例,但还不必具有 GoogleMap
的实例。最新的Google Play服务SDK(v6.5.87)为您提供了MapFragment.getMapAsync(OnMapReadyCallback)
的方法。回调将在GoogleMap
实例可用时立即运行。只有这样你才能使用它。
显然,问题出在地图本身而不是标记上。
首先,检查您用作库的谷歌播放服务版本。如果您有 6.5 版本(2014 年 12 月发布)之前的内容,请查看以下代码(Google Play 服务示例中的信用),以确保您没有空地图对象。
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.mapdemo;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
/**
* This shows how to create a simple activity with a map and a marker on the map.
* <p>
* Notice how we deal with the possibility that the Google Play services APK is not
* installed/enabled/updated on a user's device.
*/
public class BasicMapDemoActivity extends FragmentActivity {
/**
* Note that this may be null if the Google Play services APK is not available.
*/
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_demo);
setUpMapIfNeeded();
}
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {@link #setUpMap()} once when {@link #mMap} is not null.
* <p>
* If it isn't installed {@link SupportMapFragment} (and
* {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
* method in {@link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p>
* This should only be called once and when we are sure that {@link #mMap} is not null.
*/
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
我强烈推荐的另一个解决方案是获取最新的谷歌播放服务库(查看此处)。然后,您必须根据Google的本指南更改代码,使用getMapAsync()(而不是getMap())和回调,只要地图准备好使用,您就可以做任何事情,而不会再麻烦。
您是否检查过地图实际加载?我猜空指针异常实际上来自地图,而不是来自在其上放置标记。
本教程是开始使用谷歌地图(包括处理这样的异常)的绝佳指南:http://www.vogella.com/tutorials/AndroidGoogleMaps/article.html
getMap 已弃用,请改用 getMapAsync。您的活动需要实现 OnMapReadyCallback 接口,因此您可以在 onMapReady 方法中添加标记。
从文档:
getMap() 此方法已弃用。请改用getMapAsync(OnMapReadyCallback)。回调方法为您提供了一个 GoogleMap 实例,该实例保证为非 null 并可供使用。
编辑:正如其他答案所提到的,getMap()
现在实际上已经贬值了。
因此,不再推荐以下方法,但可能仍然有效。
首先,请确保您已将地图API密钥输入到您的AndroidManifest.xml
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="api-key-here" />
然后确保在布局中正确定义地图(请参阅下面的示例)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/mapView"
android:layout_width="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_height="fill_parent"
android:layout_alignParentTop="true" />
</RelativeLayout>
完成后,您可以按如下方式访问地图
android.support.v4.app.FragmentManager mFragmentManager = getSupportFragmentManager();
final SupportMapFragment mMapFragment = (SupportMapFragment) mFragmentManager.findFragmentById(R.id.mapView);
googleMap = mMapFragment.getMap();
- 首先使用此方法检查谷歌地图是否为空或非空 --> If(gMap!=null)
- 无论您是必须从url下载标记图标表单(还是)直接从url将标记图像添加到标记信息窗口中,都可能获得网络主线程异常。
- 网络主线程异常导致标记图像为空,因此您可能会在谷歌地图中获得空指针异常
溶液:
在 onCreate 方法中添加以下行
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);