Служба Android не остается в живых после закрытия приложения

Конструктор копирования используется для инициализации нового объекта с ранее созданным объектом того же класса. По умолчанию компилятор написал мелкую копию. Мелкая копия отлично работает, когда динамическое распределение памяти не задействовано, поскольку при распределении динамической памяти оба объекта указывают на одну и ту же ячейку памяти в куче, поэтому для удаления этой проблемы мы написали глубокую копию, чтобы оба объекта имели свою собственную копию атрибутов в памяти. Чтобы прочитать подробности с полными примерами и пояснениями, вы можете увидеть конструкторы C ++ .

0
задан Programm 6 March 2019 в 15:30
поделиться

1 ответ

Если вы активно закроете приложение (закрыв его из списка активности Android), Android, скорее всего, убьет ваш сервис. Вы можете видеть это в своих приложениях Logcat. Единственный реальный способ обойти это - обслуживание переднего плана.

Кроме того, onBind не будет вызываться при каждом подключении к услуге. Из документации Android :

Вы можете подключить несколько клиентов к услуге одновременно. Однако система кэширует канал связи службы IBinder. Другими словами, система вызывает метод onBind () службы для генерации IBinder только тогда, когда первый клиент связывается. Затем система доставляет тот же IBinder всем дополнительным клиентам, которые связываются с той же службой, без повторного вызова onBind ().

Во-вторых, только то, что вызывается onStartCommand, не означает, что служба создается заново. Его можно вызывать несколько раз в течение жизненного цикла службы. Например, каждый раз, когда вызывается startService, выполняется onStartCommand, но служба не обязательно воссоздается.

Кроме того, похоже, что вы не отменяете привязку службы при закрытии действия. Это делает вашу деятельность утечкой ServiceConnection и сбой вашего приложения. Это объясняет, почему вы видите, что сервис воссоздается каждый раз, когда вы закрываете и перезапускаете приложение.

Попробуйте добавить unbind в метод onPause своей деятельности:

@Override
void onPause() {
    super.onPause()
    unbindService(this.serviceConnectino)
}

Рабочая конфигурация может выглядеть следующим образом. Он реализует увеличение счетчика с помощью специальной сервисной функции, а не onBind:

MyBoundService.kt

package com.test

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log

class MyBoundService : Service() {

    abstract class MyBinder: Binder() {
        abstract fun getService(): MyBoundService
    }

    val iBinder: MyBinder = object: MyBinder() {
        override fun getService(): MyBoundService {
            return this@MyBoundService
        }
    }

    private var counter = 0

    fun increment() {
        counter ++
        Log.i("MyBoundService", "Counter: ${counter}")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.i("MyBoundService", "startCommand");
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onBind(p0: Intent?): IBinder? {
        counter++
        Log.i("MyBoundService", "Bound: ${counter}")
        return iBinder
    }

    override fun onUnbind(intent: Intent?): Boolean {
        Log.i("MyBoundService", "Unbound")
        return super.onUnbind(intent)
    }
}

MainActivity.kt

package com.test

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import android.content.ComponentName
import android.content.Context
import android.content.ServiceConnection
import android.os.IBinder
import android.util.Log
import com.test.MyBoundService

class MainActivity : AppCompatActivity() {


    private val serviceConnection: ServiceConnection = object: ServiceConnection {
        override fun onServiceDisconnected(p0: ComponentName?) {
            Log.i("MainActivity", "Service disconnected")
        }

        override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
            Log.i("MainActivity", "Service connected")
            p1?.let {
                (p1 as MyBoundService.MyBinder).getService().increment()
            }
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn_create.setOnClickListener {
            val i = Intent(this@MainActivity, MyBoundService::class.java)
            startService(i)
        }

        btn_bind.setOnClickListener {
            val i = Intent(this@MainActivity, MyBoundService::class.java)
            bindService(i, serviceConnection, Context.BIND_AUTO_CREATE)
        }
    }

    override fun onPause() {
        super.onPause()
        unbindService(serviceConnection)
    }
}
0
ответ дан fjc 6 March 2019 в 15:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: