The phenomenon of
For Android O versions 8.0 or later, the following exceptions are thrown when startService is executed in the background:
Caused by: java.lang.IllegalStateException: Not allowed to start service … app is in background uid UidRecord …
StartServic is not allowed when app is in the background
Cause analysis,
Starting with Android O, Google has added two background restrictions to control resource usage:
-
Background services
-
radio
In the background service, if the application is in the background, startService cannot be used directly.
So what is a background application? The opposite of the background is the foreground, which Google defines as follows:
-
Having visible activities (whether the activity is started or paused)
-
With front desk service
-
Associated foreground applications (wallpapers, notification listeners, etc.)
Please refer to the official link for details:
Developer.android.com/about/versi…
The solution
Since we used the background service, it must be some scenes without user awareness, so it is not possible to replace it with the foreground service.
Starting from Google’s explanation of the foreground application, you can make your application in the foreground by creating the foreground scene.
The official also mentioned JobScheduler to replace the background service, which can be used according to the business scenario.
The startService approach does not need to be abandoned entirely. In order to adapt to 8.0 mobile phones, you need to check whether the application is in the foreground and then decide whether to use startService.
There are many ways to determine whether an application is in the foreground. There are two main principles:
-
Determine the number of foreground activities by AM
-
Through callback actvitiy life cycle count (Activity callback, ActivityLifecycleCallbacks) determine whether there is the front desk interface
There are many ways to implement it, Google yourself
Setting targetSdk < 26 can also circumvent this new feature.
Source code analysis
StartService process is as follows:
ContextImpl#startServce ->
ContextImpl#startServceCommon ->
AMS#startService ->
ActiveServices#startServiceLocked ->
AMS#checkAllowBackgroundLocked
8.0.0
ContextImpl.java#startServiceCommon
The source of the log information is in the red box
ActivityServices.java#startServiceLocked
Another source of Log information: app is in background
R.startrequested Is initialized for the first time and defaults to false; FgRequired is the passed value false so you can enter the following logic;
Allowed, obtained via AMS#getAppStartModeLocked, is the decision value, meaning whether background operation is allowed or not. The returned value has multiple types (Boolean, int).
Google made a large number of submissions about background application judgment and background execution restrictions a year ago (2016~2017), as can be seen from the records:
I mentioned earlier that setting targetSdk<26 is ok, but this is only from the 8.0 feature code level analysis, and this does not prevent background service restrictions in 7.x.
ActiveServices.java # startServiceLocked
7.1.1 Whether AMS allows the background service to start The main concern is the priority of the current process and whether it has the background running permission
The middle process of 8.0AMS is slightly more complicated than 7.X, and the general process is as follows:
AMS # getAppStartModeLocked ->
AMS # appServicesRestrictedInBackgroundLocked ->
AMS # appRestrictedInBackgroundLocked
This is equivalent to a background service privilege check, as long as one of three things is satisfied:
-
There are persistent permissions
-
Background running whitelist
-
Power optimization whitelist
Can directly use background services, the first two are system applications to set;
8.0 will give priority to determine whether targetSdk is in O version and above, yes will directly return not allowed, no will determine whether there is background running permission!
Therefore, if the background running logic is required, the background running permission is first enabled for versions 8.0 or later, and the power optimization whitelist is first enabled for versions 8.0 or later.
With the update of Android version, the black technology used in the early years has gradually become invalid. Now it is urgent to focus on the design of product level and guide users to open relevant permissions.
In a word, Google’s restrictions on the background are becoming more and more strict, which not only limits all kinds of pull activities, but also limits the behavior of preempting background resources. All major apps need to do a good job of adaptation of advanced versions in advance.