MapView的onDestroy()导致UninitializedPropertyAccessException

问题描述 投票:0回答:1

我在Google Map的MapView组件中遇到了一个奇怪的问题,它会导致运行时异常UninitializedPropertyAccessException。 [在第二个配置更改(设备旋转)后,除覆盖了MapView方法的视图之外的所有其他视图中,引发了异常。因此,在处理MyMapViewFragment生命周期的com.google.android.gms.maps.MapView中,不会引发此错误,并且不会更改配置工作正常。

在我旋转设备时调用问题MyMapViewFragment.onDestroy()会销毁com.google.android.gms.maps.MapView:在其他所有视图中都出现问题:

override fun onDestroy() {
    super.onDestroy()
    googleMapView.onDestroy()
}

第二次旋转设备会导致googleMapView.onDestroy()行出现UninitializedPropertyAccessException-未初始化MapView。 MyMapViewFragment的代码:

class MyMapViewFragment : Fragment(), OnMapReadyCallback {

   private lateinit var googleMapView: com.google.android.gms.maps.MapView
   private lateinit var googleMap : GoogleMap

  override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
  ): View? {
    var view = inflater.inflate(R.layout.fragment_map_view, container, false)
    googleMapView = view.findViewById(R.id.mapView2)
    googleMapView.onCreate(savedInstanceState)
    googleMapView.getMapAsync(this)
    bottomNavigationView = requireActivity().findViewById(R.id.bottomNavigation)
    mountainCustomInfoWindow.visibility = View.INVISIBLE
    bottomNavigationView.visibility = View.VISIBLE
    return view
 }

  override fun onMapReady(map: GoogleMap) {
    googleMap = map
  }
  override fun onPause() {
     super.onPause()
     googleMapView.onPause()
  }
  override fun onResume() {
     super.onResume()
     googleMapView.onResume()
  }
  override fun onDestroy() {
     super.onDestroy()
     googleMapView.onDestroy()
  }
  override fun onLowMemory() {
     super.onLowMemory()
     googleMapView.onLowMemory()
  }
}

Stacktrace:

Process: com.hiker, PID: 25388
java.lang.RuntimeException: Unable to destroy activity {com.hiker/com.hiker.presentation.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property googleMapView has not been initialized
    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4605)
    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4623)
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4897)
    at android.app.ActivityThread.-wrap19(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1702)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6944)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
 Caused by: kotlin.UninitializedPropertyAccessException: lateinit property googleMapView has not been initialized
    at com.hiker.presentation.map.MapView.onDestroy(MapView.kt:173)
    at androidx.fragment.app.Fragment.performDestroy(Fragment.java:2830)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1028)
    at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1310)
    at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
    at androidx.fragment.app.FragmentManagerImpl.dispatchDestroy(FragmentManagerImpl.java:2644)
    at androidx.fragment.app.Fragment.performDestroy(Fragment.java:2825)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1028)
    at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
    at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
    at androidx.fragment.app.FragmentManagerImpl.dispatchDestroy(FragmentManagerImpl.java:2644)
    at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:329)
    at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:366)
    at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:210)
    at android.app.Activity.performDestroy(Activity.java:7479)
    at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1255)
    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4592)
android google-maps kotlin google-maps-android-api-2
1个回答
0
投票

更多的猜测:lateinit属性要求对该属性执行任何其他操作之前先对其进行初始化。在这种情况下,我们将使用它,因为我们只能在onCreateView中而不是在构造函数中对其进行初始化。您确实在googleMapView的第二行上初始化了onCreateView

但是,如果view.findViewById(R.id.mapView2)返回null,则可能实际上未正确初始化它。如果布局mapView2中没有ID为fragment_map_view的元素,则为这种情况。因此,验证那里确实有一个MapView。


可能发生的另一种情况是,如果该片段实际上并未附加到视图层次结构中,而是被实例化并注册到活动中。当Activity被销毁时,它销毁了Fragment并在未初始化的对象上调用了一个方法。 这里的实际情况

((请参阅注释以获取解决方案。)

© www.soinside.com 2019 - 2024. All rights reserved.