【问题标题】:Android MapFragment "NullPointerException" Error when starting app启动应用程序时Android MapFragment“NullPointerException”错误
【发布时间】:2017-03-21 03:43:42
【问题描述】:

在我尝试使用 Fragments 的小型应用程序上工作。该应用程序从 URI 中提取一些 JSON 数据。然后它创建并在列表中显示该数据。如果不涉及片段,所有这些都可以正常工作。

我正在尝试让 Google 地图显示在我的布局中该列表下方的片段中,这就是我遇到麻烦的地方。

我的 API 密钥很好。我已经查看了 StackTrace,但无法弄清楚到底发生了什么。所以,我请你们帮忙。另外,在建议之前,我已经在 Android Studio 中多次清理和重建了该应用程序。

这是我的代码,我将尝试仅显示相关位。如果您需要更多,请告诉我。

代码

MainActivity.java

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<CycloneData>> {

...

私有 CycloneMap cycloneMapFrag;

private void initMapFragment() {

    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    cycloneMapFrag = new CycloneMap();
    SupportMapFragment supportMapFragment = cycloneMapFrag;
    fragmentTransaction.add(google_map, supportMapFragment);
    fragmentTransaction.commit();
}

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

    ...

    initMapFragment();
}

}

CycloneMap.java(我试图添加的片段)

public class CycloneMap extends SupportMapFragment {

//Defining Google Map objects variables
private GoogleMap googleMapView;
boolean mapReady = false;

static final CameraPosition START_POINT = CameraPosition.builder()
        .target(new LatLng(38.1254, -101.1703))
        .zoom(3)
        .bearing(359)
        .tilt(5)
        .build();

private void initGoogleMap() {
    getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap googleMap) {

            //Setting mapReady to true
            mapReady = true;

            //Loading local instance map from Callback
            googleMapView = googleMap;

            //Set map type to Satellite view
            googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

            //Set camera at starting point, high over the middle of the U.S of A.
            initialCameraPosition(START_POINT);
        }
    });

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.cyclone_list, container, false);
}

//@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initGoogleMap();
}

private void initialCameraPosition(CameraPosition target) {
    //Setting position to the target created above
    googleMapView.moveCamera(CameraUpdateFactory.newCameraPosition(target));
}

}

XML

cyclone_list.xml 布局文件

<?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">


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!-- Layout for a list of cyclones -->
    <ListView
        android:id="@+id/cyclone_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:orientation="vertical"
        android:layout_weight="1"/>

    <!-- Layout for Google Maps Fragment -->
    <FrameLayout
        android:id="@+id/google_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
</LinearLayout>

...

</RelativeLayout>

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.palarran.cycloops">

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission     android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher_cycloops"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

    <activity
        android:name=".MenuSettingsActivity"
        android:label="@string/settings_title">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.palarran.cycloops.MenuSettingsActivity"/>
    </activity>

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="AHlaSyCIse5CB1QqYj9IqKzd7jRwGtIdjI48Mto"/>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version"/>
</application>

</manifest>

堆栈跟踪

CatLog 说:

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: com.palarran.cycloops, PID: 31964
                                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.palarran.cycloops/com.palarran.cycloops.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.v()' on a null object reference
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                                                                       at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                       at android.os.Looper.loop(Looper.java:154)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                                                                    Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.v()' on a null object reference
                                                                       at com.google.maps.api.android.lib6.impl.co.i(:com.google.android.gms.DynamiteModulesB:178)
                                                                       at com.google.android.gms.maps.internal.w.onTransact(:com.google.android.gms.DynamiteModulesB:209)
                                                                       at android.os.Binder.transact(Binder.java:499)
                                                                       at com.google.android.gms.maps.internal.IMapFragmentDelegate$zza$zza.onStart(Unknown Source)
                                                                       at com.google.android.gms.maps.SupportMapFragment$zza.onStart(Unknown Source)
                                                                       at com.google.android.gms.dynamic.zza$6.zzb(Unknown Source)
                                                                       at com.google.android.gms.dynamic.zza.zza(Unknown Source)
                                                                       at com.google.android.gms.dynamic.zza.onStart(Unknown Source)
                                                                       at com.google.android.gms.maps.SupportMapFragment.onStart(Unknown Source)
                                                                       at android.support.v4.app.Fragment.performStart(Fragment.java:2215)
                                                                       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1340)
                                                                       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
                                                                       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
                                                                       at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2893)
                                                                       at android.support.v4.app.FragmentController.dispatchStart(FragmentController.java:212)
                                                                       at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:613)
                                                                       at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
                                                                       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
                                                                       at android.app.Activity.performStart(Activity.java:6696)
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2628)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                                                                       at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                       at android.os.Looper.loop(Looper.java:154) 
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6119) 
                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

堆栈跟踪的原因

原因:java.lang.NullPointerException:尝试在空对象引用上调用接口方法“void com.google.maps.api.android.lib6.impl.bq.v()”

我浏览了 StackTrace 并阅读了有关 NullPointerExceptions 的建议文章。那里没有帮助。我无法找到或弄清楚 NullPointer 指的是什么或如何更正它。

编辑/更新

我可能遇到了 Google API 错误。如果我在模拟器上运行它,它不会像以前那样崩溃。我发现错误报告和一些 StackOverFlow 帖子说问题是由于我的手机的 USB 连接而发生的,或者如果没有 SD 卡,它会在某些手机上发生。我的手机(Nexus 5X)上没有 SD 卡,也没有其他手机可以测试。 :(

【问题讨论】:

  • 这很难调试,因为堆栈跟踪没有引用您创建的任何类和方法。都是 Android API 和 Google Maps API。
  • 是的。我会同意的。我被难住了。
  • Android 调试器是否允许您单步执行 Google Maps API 代码?当然,你必须弄清楚如何让它崩溃,这样你才能做到这一点......嗯......
  • 是的,它会的,我一直在经历。似乎在 getMapAsync(new OnMapReadyCallback() 处理 FragmentManager.java API 代码后不久就死了。我正在涉水,但是哇...发生了很多事情。:)

标签: android android-fragments


【解决方案1】:

我建议设置您的 Fragment 事务,以便您持有管理器的实例而不是事务。

// Get an instance of your custom map fragment class
// or of "new SupportMapFragment();"
SupportMapFragment mapFragment = new MyMapFragment();

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    // Add the Map Fragment to your FrameLayout container
    .replace(R.id.fragment_container, mapFragment, "MAP_FRAGMENT")
    .commit();

您可能想尝试将您的initGoogleMap() 放入您的地图片段的onResume()

【讨论】:

  • 我给了你的建议,但同样的 NullPointerException 错误。我认为我的问题是我编写 CycloneMap.Java 片段的方式。我对 OOP 还很陌生。来自网络/Unix 程序背景,OOP 有时让我感到困惑。我想我可以将所有内容都移到 MainActivity.java 中,然后在 XML 中静态地执行片段。 :(
  • @CBMidkiff 使用new SupportMapFragment() 应该允许您以编程方式添加它。这种方式对你也不起作用?
  • 我没有尝试过,因为我不确定你的意思是如何使用它?我也不确定你在哪里想出了字符串“MAP_FRAGMENT”。我猜我有点宰了它
  • 编辑此评论。我重试了,按照你建议的方式。它确实会加载地图,但不会从 CycloneMap.java 片段中加载它。它加载一个基本地图。与我昨天想出的“修复”相同。我似乎无法让 CycloneMap.java 片段代码正确运行和加载。当它被调用时,它只会产生 NullException。
  • 我仔细阅读了文档,它指出“getMapAsync”必须在主线程中运行。所以我把所有东西都移到了 MainActivity.java 中,它可以按我的意愿工作。我确定我在我的片段中做错了什么......不知道......我稍后会回到这个问题。我已经敲了3天左右的头。 :P 想做点别的事情。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多