谷歌地图应用运行正常 点击应用变更并重启Activity时崩溃如何解决
问题复现说明
我开发的是一款简单的谷歌地图应用,地图上放置了2个标记点,默认会缩放定位到其中一个标记点。直接运行程序时功能完全正常,但如果修改部分代码后点击「应用变更并重启Activity」就会触发崩溃。有时候我修改xml文件和主代码文件后保存,再重新全量运行可以绕过该错误,但我想明确知道应用持续崩溃的原因。
相关代码
MainActivity.kt
package com.example.gpsworkingnew import android.os.Bundle import androidx.fragment.app.FragmentActivity import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions class MainActivity : FragmentActivity(), OnMapReadyCallback{ private lateinit var mMap: GoogleMap override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } override fun onMapReady(googleMap: GoogleMap) { mMap = googleMap // Add a marker in Sydney and move the camera val gjovik = LatLng(60.784250, 10.686500) val gjovik2 = LatLng(60.784251, 10.687510) mMap.addMarker(MarkerOptions().position(gjovik).title("Marker in gjovik")) mMap.addMarker(MarkerOptions().position(gjovik2).title("Marker in gjovik2")) mMap.moveCamera(CameraUpdateFactory.newLatLng(gjovik)) mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(gjovik, 40f)) } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.SupportMapFragment" tools:context=".MainActivity" /> </androidx.constraintlayout.widget.ConstraintLayout>
错误日志
--------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.gpsworkingnew, PID: 7080 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.gpsworkingnew/com.example.gpsworkingnew.MainActivity}: android.view.InflateException: Binary XML file line #15 in com.example.gpsworkingnew:layout/activity_main: Binary XML file line #15 in com.example.gpsworkingnew:layout/activity_main: Error inflating class fragment at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5456) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5362) at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:58) at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5415) at android.app.ActivityThread.access$3300(ActivityThread.java:237) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2076) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: android.view.InflateException: Binary XML file line #15 in com.example.gpsworkingnew:layout/activity_main: Binary XML file line #15 in com.example.gpsworkingnew:layout/activity_main: Error inflating class fragment Caused by: android.view.InflateException: Binary XML file line #15 in com.example.gpsworkingnew:layout/activity_main: Error inflating class fragment Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f060016 type #0x3 is not valid at android.content.res.Resources.getDimensionPixelSize(Resources.java:827) at com.google.maps.api.android.lib6.impl.at.h(:com.google.android.gms.dynamite_mapsdynamite@201817052@20.18.17 (040700-0):7) at com.google.maps.api.android.lib6.impl.fc.<init>(:com.google.android.gms.dynamite_mapsdynamite@201817052@20.18.17 (040700-0):6) at com.google.maps.api.android.lib6.impl.bi.a(:com.google.android.gms.dynamite_mapsdynamite@201817052@20.18.17 (040700-0):15) at com.google.maps.api.android.lib6.impl.co.a(:com.google.android.gms.dynamite_mapsdynamite@201817052@20.18.17 (040700-0):4) at com.google.android.gms.maps.internal.o.a(:com.google.android.gms.dynamite_mapsdynamite@201817052@20.18.17 (040700-0):21) at cy.onTransact(:com.google.android.gms.dynamite_mapsdynamite@201817052@20.18.17 (040700-0):4) at android.os.Binder.transact(Binder.java:1043) at com.google.android.gms.internal.maps.zza.zzH(com.google.android.gms:play-services-maps@@17.0.1:2) at com.google.android.gms.maps.internal.zzk.onCreateView(com.google.android.gms:play-services-maps@@17.0.1:5) at com.google.android.gms.maps.zzau.onCreateView(com.google.android.gms:play-services-maps@@17.0.1:7) at com.google.android.gms.dynamic.zad.zaa(Unknown Source:4) at com.google.android.gms.dynamic.DeferredLifecycleHelper.zaa(Unknown Source:9) at com.google.android.gms.dynamic.DeferredLifecycleHelper.onCreateView(Unknown Source:25) at com.google.android.gms.maps.SupportMapFragment.onCreateView(com.google.android.gms:play-services-maps@@17.0.1:1) at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2439) at androidx.fragment.app.FragmentManagerImpl.ensureInflatedFragmentView(FragmentManager.java:1689) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1431) E/AndroidRuntime: at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1684) at androidx.fragment.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3774) at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:120) at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:405) at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:387) at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959) at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082) at android.view.LayoutInflater.inflate(LayoutInflater.java:680) at android.view.LayoutInflater.inflate(LayoutInflater.java:532) at android.view.LayoutInflater.inflate(LayoutInflater.java:479) at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:455) at android.app.Activity.setContentView(Activity.java:3468) at com.example.gpsworkingnew.MainActivity.onCreate(MainActivity.kt:18) at android.app.Activity.performCreate(Activity.java:8000) at android.app.Activity.performCreate(Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5456) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5362) at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:58) at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5415) at android.app.ActivityThread.access$3300(ActivityThread.java:237) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2076) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) I/Process: Sending signal. PID: 7080 SIG: 9
原因说明
- 核心问题是你当前使用的17.0.1版本play-services-maps SDK和Android Studio的「应用变更并重启Activity」功能存在兼容缺陷。热重启只会增量更新修改的代码和资源,不会全量重新打包,导致Maps SDK加载内部资源时读取到无效的资源ID,抛出资源找不到异常。全量运行时会重新构建整个APK,所有资源ID都是有效的,所以不会触发崩溃。
- 你当前在XML中静态声明Fragment的写法也存在潜在隐患,Activity配置变更重启时,系统会自动恢复之前的Fragment实例,重复绑定可能会引发后续的内存泄漏或者重复初始化问题。
解决方案
- 升级play-services-maps SDK到18.1.0及以上版本,高版本已经修复了和热重启功能的兼容问题,修改模块级build.gradle中的依赖声明即可。
- 若暂时不升级SDK,修改代码后直接全量运行应用即可规避崩溃,涉及布局、资源修改时不要使用热重启功能。
- 可选优化:将布局中的静态fragment标签替换为FrameLayout容器,代码中动态添加SupportMapFragment,避免配置变更带来的隐患:
修改后的activity_main.xml对应部分:
<FrameLayout android:id="@+id/map_container" android:layout_width="match_parent" android:layout_height="match_parent" />
修改后的MainActivity onCreate逻辑:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 避免重复添加Fragment var mapFragment = supportFragmentManager.findFragmentByTag("map_fragment") as SupportMapFragment? if (mapFragment == null) { mapFragment = SupportMapFragment() supportFragmentManager.beginTransaction() .add(R.id.map_container, mapFragment, "map_fragment") .commit() } mapFragment.getMapAsync(this) }
内容的提问来源于stack exchange,提问作者ElliotST
相关产品推荐
相关产品推荐

