【问题标题】:Endless running foreground service keeps Google Play services for ads in memory无休止运行的前台服务将 Google Play 广告服务保留在内存中
【发布时间】:2021-04-18 10:22:28
【问题描述】:

TL DR

我有一个应用程序,它永远运行前台服务来监控电池(温度、电量等),记录这些数据并在超出某些限制时发送通知。由于我添加了广告,即使在关闭应用程序并最终被杀死后,正在运行的服务也会使用大量内存,这使我的应用程序无用。我搜索了几个小时,找不到任何人报告类似的事情,所以我想我做错了什么。


我在底部导航视图中使用带有单个活动和多个片段的 MVVM 模式。在MainActivity, onCreate() 我初始化服务:

 val serviceIntent = Intent(this, MyService::class.java)
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
       startForegroundService(serviceIntent)
 } else {
       startService(serviceIntent)
 }

MyService.kt我打电话

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        createNotificationChannels()
        startForegroundForService()
    } else {
        startForeground(1, Notification())
    }
    return START_REDELIVER_INTENT
}


private fun startForegroundForService() {
            val notificationBuilder = NotificationCompat.Builder(this, TEMP_NOTIFICATION_CHANNEL_ID)
        val notification = notificationBuilder.setOngoing(false)
                .setPriority(NotificationManager.IMPORTANCE_LOW)
                .setCategory(Notification.CATEGORY_SYSTEM)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setOnlyAlertOnce(true)
                .setContentIntent(resultPendingIntent)
                .build()
        startForeground(TEMP_NOTIFICATION_ID, notification)
}

如果应用程序被排除在电池优化之外,这可以正常工作,并且服务会持续运行数天。使用的内存大约是 50MB,因为我可以在“运行服务”中查看开发者选项。

当我在一些片段中添加横幅广告时,问题就开始了。在MainActivity 我调用MobileAds.initialize(this) 并且在每个片段中这个代码:

private lateinit var mAdViewBanner: AdView

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        .....
        mAdViewBanner = binding.adBanner
        ....
    }

    override fun onPause() {
        super.onPause()
        mAdViewBanner.pause()
    }

    override fun onDestroy() {
        mAdViewBanner.destroy()
        super.onDestroy()
    }

    override fun onResume() {
        super.onResume()
        mAdViewBanner.resume()
    }

我添加了日志行以检查在浏览应用程序时是否调用了这些行,包括当应用程序通过后退按钮关闭时 MainActivity 中的 onDestroy。主片段在 MainActivity 之后被销毁,否则,我没有看到任何奇怪的行为。横幅广告被销毁(或至少它们的实例被调用销毁)。

该服务通过 4 个进程继续运行,其中两个是 Google Play 服务。该应用程序的已用内存量约为 400MB(而不是预期的 50MB)。即使 30 分钟后未打开应用,这些 Play 服务也不会停止。一段时间后,所有服务和进程都被杀死。

我找不到在关闭应用程序时删除这些 Google Play 服务的方法。该应用在作为前台服务运行并被关闭时不应使用如此多的内存。

我尝试在单独的进程中运行该服务。这解决了高 RAM 量和播放服务的问题,但阻止了应用程序正常工作。当我将服务写入操作调用到应用程序存储库时,不再编写 Room 数据库。 有没有其他方法可以做到这一点?我没有尝试过 IPC,但我想这不会解决第一个问题,因为我必须继续为数据库运行第二个进程,这可以让 Play Services 继续运行。

【问题讨论】:

    标签: android admob google-play-services


    【解决方案1】:

    如果有足够的可用内存,Android 会缓存一些进程。 如您所说,如果您在 30 分钟后打开应用程序,您会发现它的加载速度更快。当没有足够的内存时,垃圾收集器会清除它。 Dialog 类也是如此,有时会被人们误解,但这不是问题。

    在 Admob 官方文档中,某些类型的广告(例如 Native Ads)需要您使用特殊功能来防止内存泄漏。但是,如果 Activity 关闭,Garbage Collector 会自动清除您的内存。服务也是如此,所以我认为这不是您的应用程序的问题。

    【讨论】:

      猜你喜欢
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多