0

I have a main service which should always be running in the background in my Android application for handling a bluetooth device connection and feeding data to it.

According to these questions, it is a normal behavior if my service live in my app process to get killed when app closes,

But I even tried running my service in a separate process using this tag android:process=":service" inside my manifest but it also get killed and restarted when my app get killed!

More info: I start my service in my application onCreate method, and for binding to my service in my activity I use BIND_AUTO_CREATE, which generally I am not sure is it correct or not.

update: I also have another service which bind inside my current service, I am not sure if it might be source of issue!

more update: I am using dagger for DI, is it possible by mistake I am using application context for creating some objects inside my service!! could this be the cause of this issue?

some more update I separate dagger components for my service and now application and service got no common objects, but problem still remains.

update with a sample code which got the same issue Here is the Application class:

class MyApplication:Application() {

    override fun onCreate() {
        super.onCreate()

        startService(Intent(this, MyService::class.java))
    }
}

Here is the Service class:

class MyService : Service() {

    private val mBinder = MyBinder()

    inner class MyBinder : Binder() {
        internal val service: MyService
            get() = this@MyService
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.i(TAG, "onStartCommand")

        return START_STICKY
    }

    override fun onCreate() {
        super.onCreate()

        Log.i(TAG, "onCreate")
    }

    override fun onBind(intent: Intent): IBinder? {
        Log.i(TAG, "onBind")

        return mBinder
    }

    override fun onUnbind(intent: Intent): Boolean {
        Log.i(TAG, "onUnbind")

        return super.onUnbind(intent)
    }

    override fun onDestroy() {
        Log.i(TAG, "onDestroy")

        super.onDestroy()
    }

    companion object {
        val TAG = "MyService"
    }
}

This is the Activity:

class MainActivity : AppCompatActivity() {
    lateinit var context: Context

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.i(TAG, "onCreate")

        context = this
    }

    //connect to the service
    val myServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            Log.i(TAG, "onServiceConnected")

            val binder = service as? MyService.MyBinder

            // ...
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            Log.i(TAG, "onServiceDisconnected")
        }
    }

    override fun onResume() {
        super.onResume()
        Log.i(TAG, "onResume")

        val intent = Intent(context, MyService::class.java)
        bindService(intent, myServiceConnection, Context.BIND_AUTO_CREATE);
    }

    override fun onPause() {
        super.onPause()
        Log.i(TAG, "onPause")

        unbindService(myServiceConnection)
    }

    companion object {
        val TAG = "MainActivity"
    }
}

Last but not least, the Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mirhoseini.stickyservice">

    <application
        android:name=".MyApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"
            android:process=":service" />
    </application>

</manifest>
Mohsen Mirhoseini
  • 8,454
  • 5
  • 34
  • 59

1 Answers1

0

It is a normal behavior for a service to stop when the application main thread stops.

Personally, I don't agree with using an internal service in a separate process for the regular development and functionality sharing between modules. A worker or IntentService is the more appropriate candidate most of the times.

To keep your service alive after user exits the app, try one of the scheduled threading mechanism that suits your needs, best :

1- TimerTask ( not really recommended !)

2- Executors.newScheduledThreadExecutor

3- AlarmManager

4- JobScheduler

Farhad
  • 12,178
  • 5
  • 32
  • 60
  • I want to use my background service to keep a bluetooth connection alive and running, which means it is not a time related service which could be interrupted or run in different periods. Any idea for my situation? – Mohsen Mirhoseini Jul 21 '17 at 22:06
  • IntentService seems good. It maintains a queue of works, start the service automatically and keeps it alive while there's work in the queue. – Farhad Jul 21 '17 at 22:15
  • But it will die when there is no task to do. By the way, I need my bluetooth connection object in my service to reuse it! – Mohsen Mirhoseini Jul 21 '17 at 22:16
  • sure. If your service is going to poll for an external condition to fire some other modules, I guess timed-polling with an executor or timer task may be the solution – Farhad Jul 21 '17 at 22:18
  • It is not possible to keep service running, You have to prepare your code for a restart and being able to continue. I added more details that I found during my researches and testes. – Mohsen Mirhoseini Jul 22 '17 at 14:21