【发布时间】: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