This one will require a bit of context, please bare with me...
I have migrated a dependency for evaluating NFC data to a new application. Whenever an NFC tag is discovered, my application will spawn an Activity to handle the event. In the onCreate
function of this NfcActivity
, a background service (let's call it MyNfcHelperService
) is started to retrieve some data on the scanned tag:
class NfcActivity : AppCompatActivity() {
/*...*/
override fun onCreate(savedInstanceState: Bundle?) {
/*...*/
val intent = Intent(this, MyNfcHelperService::class.java)
.putExtra(/*...*/)
startService(intent)
}
}
The work produced by this service is later retrieved and used by the NfcActivity
. It all used to work just fine, but once released into the wild we noticed some crashes, which would report Not allowed to start service Intent
on the startService(intent)
call.
I quickly came across this related post, suggesting this is due to some improvements in RAM management on background processes (introduced in Android 8).
Following the accepted answer and comments raised, I studied the docs on JobIntentServices and ended up with a similar setup. I would've liked to drop the MyNfcHelperService
all together and move its logic into the MyJobIntentService
. But what happens inside MyNfcHelperService
is an absolute black-box to me. Thus, I wrapped the aforementioned service inside the onHandleWork
of my derived JobIntentService
like so:
class MyJobIntentService: JobIntentService() {
companion object {
private const val JOB_ID = 1000
fun start(context: Context) {
val intentPkm = Intent(context, MyNfcHelperService::class.java)
.putExtra(/*...*/)
enqueueWork(context, intentPkm)
}
private fun enqueueWork(context: Context, intent: Intent) {
enqueueWork(context, MyJobIntentService::class.java, JOB_ID, intent)
}
}
override fun onHandleWork(intent: Intent) {
applicationContext.startService(intent)
}
}
Then I applied this class in NfcActivity
:
class NfcActivity : AppCompatActivity() {
/*...*/
override fun onCreate(savedInstanceState: Bundle?) {
/*...*/
MyJobIntentService.start(applicationContext)
}
}
Thus far, the code seems to work. But I am hesitant to release it into the wild, because it feels a bit hacky and I am unsure if this solution actually solved the aforementioned issue. After all, I understand that this infrastructure creates a background service from a scheduled job.
So, is my code robust towards the java.lang.IllegalStateException: Not allowed to start service Intent
error, or did I totally head the wrong way? If the latter is the case, can anyone suggest an alternate approach, taking into account that I cannot access the guts of MyNfcHelperService
?