首先并非全部app的Service后台运行都会被系统限制。java
知足如下两个特色的APP,内的Service,可能会受到系统限制android
必须在android 8.0以上的设备上bash
APP的 targetSdkVersion 配置大于等于26app
APP的targetSdkVersion的配置在app/build.gradle文件中ide
android {
defaultConfig {
targetSdkVersion 26 //此配置
}
...
}
复制代码
当APP处于空闲期时,将会有以下两个限制:oop
java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.compat.test/com.test.Service4 }: app is in background uid UidRecord{a0d4e51 u0a84 CEM bg:+1m2s21ms idle procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1505)
at android.app.ContextImpl.startService(ContextImpl.java:1461)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
at com.test.MainActivityV2$8.run(MainActivityV2.java:153)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
复制代码
被回收的现象,就和咱们本身主动调用Context.stopService()同样。 Service将会被执行:onDestory()生命周期方法。post
注意:gradle
这里千万要注意,理解:app处在空闲期,是什么意思?ui
空闲期,在,官方文档的英文描述为:idle。google
app处在后台,并不等于处在空闲期;
app处在后台,并不等于处在空闲期;
app处在后台,并不等于处在空闲期;
APP处于后台,是进入空闲期的必要条件,但不是充分条件。
例如:
Model PixelXL手机, android8.0.0系统:在APP进入后台状态,并保持处于后台状态1分钟后,才进入空闲期。
APP从开始处于后台,到,正式进入空闲期的 这1分钟期间,app能够随意startService是不会抛出异常的。App内的Service也不会被系统主动回收。
在这1分钟期间,用户若是打开APP,将APP置为前台,那么下次进入后台后须要从新计时,从新进入后台保持1分钟才会进入空闲期。
APP存在常驻通知栏时,是否属于前台APP?
APP什么状况下会进入空闲期?
如何判断App处在后台?
APP进入空闲期时,如何防止Service不被Stop
APP处在空闲期时,如何启动Service,不引起Crash
若是只是普通的通知栏,并无什么卵用的。
只有经过 Service.startForeground(int id, Notification notification) 启动的通知栏,才能让app成为前台APP。
以下图,前台Service的通知栏。
再次强调,经过 NotificationManager.notify(int id, notification) 显示的普统统知,不会让app成为前台APP,也不会让进程成为前台进程。必须经过Service.startForeground(int id, Notification notification)方法现实的通知栏才有用。
APP处于后台以后,并不会当即进入空闲期,须要过几分钟,官方文档并无明确时长。
Model PixelXL android8.0.0 在app进入后台状态1分钟后才进入空闲期;
在模拟器上也是1分钟后进入空闲期;
那么如何判断App处在后台?这里有点复杂,须要耐心捋一捋。
知足如下任一,一个条件的APP都属于前台,Service运行不受任何限制。
【详见:下篇,突破android o Service限制】juejin.im/post/5dd16f…
好比说,输入法APP永远是一个前台APP,他被系统的前台进程绑定,因此他Service的能力永远不会被限制。
再好比说,若是APP有可见Activity时,在APP中能够随意调用Context.startService(),也不会引起crash。
developer.android.google.cn/about/versi…
英语基础好的盆友,强烈建议,把整片官方文档读一遍。
The system distinguishes between foreground and background apps. (The definition of background for purposes of service limitations is distinct from the definition used by memory management; an app might be in the background as pertains to memory management, but in the foreground as pertains to its ability to launch services.)An app is considered to be in the foreground if any of the following is true:
1) It has a visible activity, whether the activity is started or paused.
2) It has a foreground service.
3) Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content providers. For example, the app is in the foreground if another app binds to its:
a. IME
b. Wallpaper service
c. Notification listener
d. Voice or text service
If none of those conditions is true, the app is considered to be in the background.
复制代码
赞美是一种美德,点个赞再走啊,老铁