Связанный сервис утечки памяти - PullRequest
3 голосов
/ 22 мая 2019

Я написал базовый связанный сервис на основе документации Android , но LeakCanary сообщает мне, что сервис протекает.

  1. Есть утечка или я неправильно настроил LeakCanary?
  2. Как мне написать связанный сервис, который не пропускает?

Код

class LocalService : Service() {

  private val binder = LocalBinder()
  private val generator = Random()

  val randomNumber: Int
    get() = generator.nextInt(100)

  inner class LocalBinder : Binder() {
    fun getService(): LocalService = this@LocalService
  }

  override fun onBind(intent: Intent): IBinder {
    return binder
  }

  override fun onDestroy() {
    super.onDestroy()
    LeakSentry.refWatcher.watch(this) // Only modification is to add LeakCanary
  }
}

Если я связываюсь с сервисом из действия следующим образом, LeakCanary обнаруживает, что сервис просочился

class MainActivity: Activity() {

  private var service: LocalService? = null
  private val serviceConnection = object: ServiceConnection {
    override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
      service = (binder as LocalBinder).getService()
    }
    override fun onServiceDisconnected(name: ComponentName?) {
      service = null
    }
  }

  override fun onStart() {
    super.onStart()
    bindService(Intent(this, LocalService::class.java), serviceConnection, BIND_AUTO_CREATE)
  } 

  override fun onStop() {
    super.onStop()
    service?.let {
      unbindService(serviceConnection)
      service = null
    }
  }
}
┬
├─ com.example.serviceleak.LocalService$LocalBinder
│    Leaking: NO (it's a GC root)
│    ↓ LocalService$LocalBinder.this$0
│                               ~~~~~~
╰→ com.example.serviceleak.LocalService
​     Leaking: YES (RefWatcher was watching this)

1 Ответ

2 голосов
/ 30 мая 2019

Не знаю, поздно ли отвечать, но после прочтения вашего вопроса я также установил в своем проекте leakCanary и обнаружил эту утечку. Я был уверен, что это из-за внутреннего связующего класса, который содержит ссылку на внешний класс, который здесь является сервисом. Вот почему в вашем журнале утечек он показывает, что LocationService протекает. Я нашел решение @commonsguy здесь и реализовал решение на более простом примере здесь . Надеюсь это поможет. Продолжайте кодировать, будьте благословенны.

...