2

I'm starting an IntentService from MainActivity:onCreate and I noticed this crash from the crash reporting only on Android Oreo above:

java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.company.mobile/com.company.mobile.gcm.RegistrationIntentService }: app is in background uid UidRecord{c96fbae u0a184 TPSL idle procs:1 seq(0,0,0)}
    at android.app.ContextImpl.startServiceCommon()(ContextImpl.java:1577)
    at android.app.ContextImpl.startService()(ContextImpl.java:1532)
    at android.content.ContextWrapper.startService()(ContextWrapper.java:664)
    at cs.a()(FirebaseUtility.java:42)
    at com.company.mobile.MainActivity.onCreate()(MainActivity.java:81)
    at android.app.Activity.performCreate()(Activity.java:7136)
    at android.app.Activity.performCreate()(Activity.java:7127)
    at android.app.Instrumentation.callActivityOnCreate()(Instrumentation.java:1271)
    at android.app.ActivityThread.performLaunchActivity()(ActivityThread.java:2893)
    at android.app.ActivityThread.handleLaunchActivity()(ActivityThread.java:3048)
    at android.app.servertransaction.LaunchActivityItem.execute()(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks()(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute()(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage()(ActivityThread.java:1808)
    at android.os.Handler.dispatchMessage()(Handler.java:106)
    at android.os.Looper.loop()(Looper.java:193)
    at android.app.ActivityThread.main()(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke()(Method.java:-2)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run()(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main()(ZygoteInit.java:858)

Some of you might say this is a duplicate question of this, this, and this. I'm not looking for a how-to answer, rather I'm looking for an explanation why this is happening. I know this issue is because of Background Execution Limits on Android O and I already knew how to fix this by using JobIntentService. I just want to know why this crash is happening in MainActivity:onCreate().

As far as I understand, this issue should only be happening when I'm starting a service while the app is in background, for example after onStop() is called. How could my app even be in the background while MainActivity onCreate is invoked? Are there any scenarios where onCreate is invoked but app is still in background?

toktorio
  • 71
  • 2
  • 5

2 Answers2

5

Your Activity is only considered to be in the foreground once onResume() has been called. That's why starting the IntentService from onCreate() is not allowed

Quoting from Processes and Application Lifecycle

A foreground process is one that is required for what the user is currently doing. Various application components can cause its containing process to be considered foreground in different ways. A process is considered to be in the foreground if any of the following conditions hold:

  • It is running an Activity at the top of the screen that the user is interacting with (its onResume() method has been called).[...]
Bö macht Blau
  • 12,820
  • 5
  • 40
  • 61
  • 4
    I'm having this error reported mostly by P devices (and a few Oreo devices). We target 27 and call `startService()` from the activity's `onResume()`. I'm wondering if we should be posting this to a handler, so that it's executed after `onResume()` completes? Unfortunately I can't reproduce it. I only see crash reports. – Carmen Nov 28 '18 at 11:08
  • 5
    Update: I found a scenario where the app is in `onResume()`, but not in the foreground: if the app's activity is launched when the device screen is locked. I don't know how this can happen for real users, but it's possible to reproduce this crash by doing this with adb: With the app stopped and the screen locked, run `adb shell am start -n com.example.app/com.example.app.main.MainActivity`. I've added this info to the Google bug report: https://issuetracker.google.com/issues/113122354 – Carmen Nov 28 '18 at 13:42
0

Extending Carmen's answer from comments above. (I don't have rep to post right now.)

One way you get onResume called while the application is still in the background and subject to the startService security constraints is as follows:

NotificationCompat.Builder builder =...;
builder.setPriority(NotificationCompat.PRIORITY_HIGH)
       .setCategory(NotificationCompat.CATEGORY_ALARM);

Intent fullScreenIntent = new Intent(this, UrgentMessageActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
                            fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

builder.setFullScreenIntent(fullScreenPendingIntent, true);

Hopefully this is just a bug in the OS.

daveb
  • 21
  • 2