You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android PlacesClient未关闭引发垃圾回收错误问题求助

解决Google Maps Places Client退出Fragment时的ManagedChannel未关闭错误

问题重现

使用以下代码创建Places Client:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (!Places.isInitialized()) {
        Places.initialize(this.requireActivity(), BuildConfig.MAP_API_KEY)
    }

    placesClient = Places.createClient(requireActivity())
}

退出地图Fragment时抛出错误:

*\~*\~*\~
Previous channel {0} was garbage collected without being shut down!
\~*\~*\~*
Make sure to call shutdown()/shutdownNow() 
java.lang.RuntimeException: ManagedChannel allocation site

at com.google.android.libraries.places.internal.zzbme.<init>(com.google.android.libraries.places:places@@3.5.0:3)
at com.google.android.libraries.places.internal.zzbmf.<init>(com.google.android.libraries.places:places@@3.5.0:2)
at com.google.android.libraries.places.internal.zzbmd.zza(com.google.android.libraries.places:places@@3.5.0:18)
at com.google.android.libraries.places.internal.zzazt.zza(com.google.android.libraries.places:places@@3.5.0:1)
at com.google.android.libraries.places.internal.zzjn.zza(com.google.android.libraries.places:places@@3.5.0:26)
at com.google.android.libraries.places.api.Places.zza(com.google.android.libraries.places:places@@3.5.0:7)
at com.google.android.libraries.places.api.Places.createClient(com.google.android.libraries.places:places@@3.5.0:3)
at com.FragmentMapLocation.onCreate(FragmentChargerMapLocation.kt:71) at androidx.fragment.app.Fragment.performCreate(Fragment.java:3094) at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:504)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:268)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943)
...

尝试在onStop置空placesClient、onDestroy调用close(),但错误依旧:

override fun onStop() {
    super.onStop()
     placesClient = null
}

override fun onDestroy() {
    super.onDestroy()
    // Shut down the PlacesClient
         try {
             (placesClient as? AutoCloseable)?.close()
         } catch (e: Exception) {
             e.printStackTrace()
         }
}

解决方案

问题核心是调用close()前已经把placesClient置空,导致close()根本没有执行。调整逻辑顺序即可解决:

  1. 移除onStop中的置空操作
  2. 在onDestroy或onDestroyView中先执行close(),再置空对象

修改后的代码示例:

override fun onDestroy() {
    super.onDestroy()
    // 先关闭资源再置空对象
    try {
        (placesClient as? AutoCloseable)?.close()
    } catch (e: Exception) {
        e.printStackTrace()
    }
    placesClient = null
}

// 移除onStop里的置空代码
override fun onStop() {
    super.onStop()
}

如果Fragment存在复用场景(onDestroy不会立即触发),更推荐在onDestroyView中执行关闭操作:

override fun onDestroyView() {
    super.onDestroyView()
    try {
        (placesClient as? AutoCloseable)?.close()
    } catch (e: Exception) {
        e.printStackTrace()
    }
    placesClient = null
}

原理说明

PlacesClient内部的ManagedChannel需要显式关闭才能释放底层资源,若先置空placesClient,后续的close()调用会因为对象为null被跳过,导致Channel未被正确关闭,触发垃圾回收时的报错。

内容的提问来源于stack exchange,提问作者Praveen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:22:16