我们遇到了 Play Console 和 Firebase Crashlytics 上报告的大量 ANR。两者的堆栈跟踪都指向 Google 地图中的同一类 MapView。我正在分享我们在 Firebase Crashlytics 中获得的堆栈跟踪。
设备:75% Vivo 9% 小米 13% oppo 3%
操作系统:58% android11 32% android12 10%
SDK版本:
播放服务地图 19.0.0
播放服务位置 21.3.0
播放服务广告23.3.0
(https://i.sstatic.net/cWAWBBug.png)
(https://i.sstatic.net/D2hGfk4E.png)
如何避免此类ANR
代码
/**
*
*/
private fun setStampView(savedInstanceState: Bundle?) {
.......
// Google Map View
mMapView = findViewById(R.id.map_view)
// Google Map Key
val mapKey = BuildConfig.MAPS_API_KEY
if(mapKey.isNotEmpty()){
val mapViewBundle = savedInstanceState?.getBundle(mapKey)
mMapView.onCreate(mapViewBundle)
}
mMapView.getMapAsync(this)
// FusedLocationProviderClient
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
//
mGeocoder = Geocoder(this, Locale.getDefault())
}
override fun setActityView(savedInstanceState: Bundle?) {
super.setActityView(savedInstanceState)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.activity_layout_main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
// v.setPadding(systemBars.left, systemBars.top, systemBars.right, 0)
mScreenTop = systemBars.top
mScreenBottom = systemBars.bottom
val displayMetrics = resources.displayMetrics
// val screenHeight = displayMetrics.heightPixels
mScreenWidth = displayMetrics.widthPixels
// 获取广告宽度
mAdWidth = (mScreenWidth / displayMetrics.density).toInt()
mBottomSystemBarsHeight = systemBars.bottom
setBoottomSysToolViewHeight(mBottomSystemBarsHeight)
insets
}
// 设置状态栏图标颜色为白色(亮色)
WindowCompat.getInsetsController(window, window.decorView).apply {
isAppearanceLightStatusBars = false // 设置为 false 使图标变为白色
}
ImageUtils.init(applicationContext)
GPSMapCameraApp.gAppSharedPre?.let {
// 保存主界面当前是否为激活的最高界面
saveSPBoolean(it, SP_KEY_MAIN_IS_NOW_ACTIVATE, true)
}
// 埋点
logEvent(FireBaseEvent.ONE_PV, FireBaseEvent.PV_CAMERA_PAGE)
// 埋点
logEvent(FireBaseEvent.TAKEPHOTO_PROCESS, FireBaseEvent.CAMERA_PAGE_SHOW)
// 判断是否为新用户
if (GPSMapCameraApp.gIsFirst) {
// 埋点
logEvent(FireBaseEvent.NEW_USER_PROCESS, FireBaseEvent.NEW_USER_CAMERA_PAGE)
}
// 初始化声音播放
initMediaPlayer()
// 整个Activity区域
mCLMain = findViewById(R.id.activity_layout_main)
// 设置Google广告
setGoogleAdView()
// 设置相机预览全部区域
setAllCameraPreview()
mClTop = findViewById(R.id.main_cl_top_view)
// 设置按钮
m_imgTopSetting = findViewById(R.id.main_img_top_setting)
// 设置按钮 外部区域
mRlTopSetting = findViewById(R.id.main_rl_top_setting_external)
mRlTopSetting.setOnClickListener {
// 跳转到设置界面
gotoSettingActivity()
}
// 闪光灯按钮
mImgTopFlash = findViewById(R.id.main_img_top_flash)
when (currentFlashMode) {
ImageCapture.FLASH_MODE_AUTO -> {
mImgTopFlash.setImageResource(R.mipmap.ic_camera_flash_auto)
}
ImageCapture.FLASH_MODE_OFF -> {
mImgTopFlash.setImageResource(R.mipmap.ic_camera_flash_off)
}
ImageCapture.FLASH_MODE_ON -> {
mImgTopFlash.setImageResource(R.mipmap.ic_camera_flash_on)
}
else -> {
mImgTopFlash.setImageResource(R.mipmap.ic_camera_flash_auto)
}
}
// 闪光灯按钮触摸区域
mRlTopFlash = findViewById(R.id.main_rl_top_flash_external)
mRlTopFlash.setOnClickListener {
// 显示闪光灯选择弹出对话框
// showFlashPopupWindow(mImgTopFlash)
if(::mllCameraFlashSet.isInitialized) {
if(mBShowCameraFlashSet) {
mBShowCameraFlashSet = false
// 隐藏 Camera闪光灯设置相关界面
mllCameraFlashSet.visibility = View.GONE
} else {
mBShowCameraFlashSet = true
// 显示 Camera闪光灯设置相关界面
mllCameraFlashSet.visibility = View.VISIBLE
}
}
}
// 摄像头旋转按钮
mImgTopRotate = findViewById(R.id.main_img_top_rotate)
mRlTopRotate = findViewById(R.id.main_rl_top_flash_rotate)
mRlTopRotate.setOnClickListener {
// 摄像头旋转
rotateCamera()
}
// 相机设置按钮
mImgCameraSet = findViewById(R.id.main_img_top_camera_set)
// mImgCameraSet.setImageResource(R.mipmap.ic_camera_set)
// 相机设置按钮触摸区域
mRlTopCameraSet = findViewById(R.id.main_rl_top_camera_set_external)
mRlTopCameraSet.setOnClickListener {
//
if (::mRlCameraSet.isInitialized) {
if (mBShowCameraSet) {
mBShowCameraSet = false
// 隐藏 Camera设置相关界面
mRlCameraSet.visibility = View.GONE
} else {
mBShowCameraSet = true
// 显示 Camera设置相关界面
mRlCameraSet.visibility = View.VISIBLE
}
}
}
// 聚焦Icon
mImgCameraFocus = findViewById(R.id.main_img_camera_focus)
// 覆盖在预览视图上的网格
mGridOverlayView = findViewById(R.id.main_view_camera_grid)
if (mBShowCameraSetGrid) {
mGridOverlayView.visibility = View.VISIBLE
} else {
mGridOverlayView.visibility = View.GONE
}
// 闪光界面
mViewFalsh = findViewById(R.id.main_view_falsh)
// 设置底部工具相关区域
setBottomToosView()
// 设置相机设置相关界面
setCameraSetView()
// 设置相机闪光灯模式设置相关界面
setCameraFlashSetView()
// 设置相机缩放信息界面
setZoomInfoView()
// 设置 stemp信息界面
setStampView(savedInstanceState)
// 设置横竖屏切换
setOrientationChanged()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mContext = this
// 新建View之前初始化
initBeforeCreateView()
enableEdgeToEdge()
// 设置
setContentView(setActivityLayout())
// 设置Actity View
setActityView(savedInstanceState)
// 新建View之后初始化
initAfterCreateView()
}
android“build.gradle.kts(项目)”:
buildscript {
dependencies {
classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
}
}
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.jetbrains.kotlin.android) apply false
id("com.google.gms.google-services") version "4.4.2" apply false
id("com.google.firebase.crashlytics") version "3.0.2" apply false
}
android“build.gradle.kts(模块:应用程序)”:
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
}
......
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.viewpager2)
implementation(libs.androidx.recyclerview)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
// ViewModel
implementation(libs.lifecycle.viewmodel.ktx)
implementation(libs.fragment.ktx)
implementation(libs.activity.ktx)
// CameraX
implementation(libs.camera.core)
implementation(libs.camera.camera2)
implementation(libs.camera.lifecycle)
implementation(libs.camera.view)
implementation(libs.camera.video)
// CameraX KTX
implementation(libs.camera.extensions)
// Firebase
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics.ktx)
implementation(libs.firebase.crashlytics.ktx)
// Google
// Maps SDK for Android
implementation(libs.google.play.services.maps)
implementation(libs.google.play.services.location)
// google ads
implementation(libs.play.services.ads)
//
// implementation(libs.permissionx)
//
implementation(libs.bumptech.glide)
//
implementation(libs.chrisbanes.photoview)
// Lottie 动画
implementation(libs.lottie.compose)
// exoplayer
implementation(libs.google.android.exoplayer)
// AgentWeb
implementation(libs.agentweb.core)
//
implementation(libs.getActivity.multiLanguages)
//
implementation(libs.retrofit2.retrofit)
implementation(libs.retrofit2.converter.gson)
implementation(libs.okhttp3.okhttp)
implementation(libs.okhttp3.logging.interceptor)
//
implementation(libs.me.samlss.broccoli)
}
“libs.version.toml”
[versions]
........
#Firebase
firebaseBom = "33.1.2"
#Google
# Maps SDK for Android
playServicesMaps = "19.0.0"
playServicesLocation = "21.3.0"
playServicesAds = "23.3.0"
......
[libraries]
.........
#Firebase
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" } firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx" } firebase-crashlytics-ktx = { module = "com.google.firebase:firebase-crashlytics-ktx" }
#Google
#Maps SDK for Android
google-play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" }
google-play-services-location = { group = "com.google.android.gms", name = "play-services-location", version.ref = "playServicesLocation" }
play-services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "playServicesAds"}
日志:
main (runnable):tid=1 systid=16033
at com.google.maps.api.android.lib6.phoenix.am.run(:com.google.android.gms.policy_maps_core_dynamite@[email protected]:507)
at com.google.maps.api.android.lib6.impl.cg.aG(:com.google.android.gms.policy_maps_core_dynamite@[email protected]:52)
at com.google.maps.api.android.lib6.impl.ee.d(:com.google.android.gms.policy_maps_core_dynamite@[email protected]:24)
at com.google.android.gms.maps.internal.r.bt(:com.google.android.gms.policy_maps_core_dynamite@[email protected]:158)
at m.axu.onTransact(:com.google.android.gms.policy_maps_core_dynamite@[email protected]:21)
at android.os.Binder.transact(Binder.java:1043)
at com.google.android.gms.internal.maps.zza.zzc(zza.java:2)
at com.google.android.gms.maps.internal.zzl.onCreate(zzl.java:3)
at com.google.android.gms.maps.zzah.onCreate(com.google.android.gms:play-services-maps@@19.0.0:3)
at com.google.android.gms.dynamic.zac.zab(com.google.android.gms:play-services-base@@18.4.0:1)
at com.google.android.gms.dynamic.zaa.onDelegateCreated(zaa.java:3)
at com.google.android.gms.maps.zzai.zzb(com.google.android.gms:play-services-maps@@19.0.0:5)
at com.google.android.gms.maps.zzai.createDelegate(com.google.android.gms:play-services-maps@@19.0.0:1)
at com.google.android.gms.dynamic.DeferredLifecycleHelper.zaf(com.google.android.gms:play-services-base@@18.4.0:6)
at com.google.android.gms.dynamic.DeferredLifecycleHelper.onCreate(DeferredLifecycleHelper.java:1)
at com.google.android.gms.maps.MapView.onCreate(com.google.android.gms:play-services-maps@@19.0.0:4)
at gpsmapcamera.timestampcamera.geotagphoto.gpscamera.module.main.MainActivity.setStampView(MainActivity.kt:3698)
at gpsmapcamera.timestampcamera.geotagphoto.gpscamera.module.main.MainActivity.setActityView(MainActivity.kt:1693)
at gpsmapcamera.timestampcamera.geotagphoto.gpscamera.common.BaseActivity.onCreate(BaseActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:8119)
at android.app.Activity.performCreate(Activity.java:8103)
大部分手机都可以正常使用。vivo手机上经常出现ANR,这些vivo手机不在中国。如何避免此类 ANR
我们也面临同样的问题。如果有人有解决方案,请提供。