Background execution not allowed:
来源:互联网 发布:施工组织设计软件 编辑:程序博客网 时间:2024/06/03 13:41
The CommonsBlog
Android O and the Implicit Broadcast Ban
One of the more controversial changes in Android O — for apps with a sufficiently-high targetSdkVersion — is the effective ban on implicit broadcasts. Let’s take a deeper dive into what this means and why we are here.
WTF? (W = What)
On Android O, code like this no longer works the way that you expect:
sendBroadcast(new Intent(“this.is.an.implicit.broadcast”));
Normally, this broadcast would be received by all receivers that are registered for that custom action string. Even on O, two sets of receivers will still receive the broadcast:
Those whose apps have targetSdkVersion of 25 or lower
Those that were registered via registerReceiver() of some already-running process
However, manifest-registered receivers of apps with a higher targetSdkVersion will not receive the broadcast. Instead, a message like this one will appear in LogCat:
04-11 14:12:36.340 753-763/? W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.commonsware.cwac.cam2.demo flg=0x4000010 (has extras) } to com.commonsware.android.sysevents.pkg/.OnPackageChangeReceiver
WTF? (W = Why)
You might think that the concern was tied to the battery, as this seems like another front in the ongoing “war on background processing” that has been going on since Doze mode was introduced in Android 6.0.
As it turns out, battery is of secondary importance. The real reason is process churn.
Quoting a Google engineer, who may or may not be Dianne Hackborn:
To help understand what is going on, I need to clarify that the purpose of this change is not directly related to battery use, but rather to address long-standing issues we have had in the platform where devices that are under memory pressure can get in to bad thrashing states. Very often these states are due to broadcasts: some broadcast or broadcasts are being sent relatively frequently, which a lot of applications are listening to through their manifest (so need to be launched to receive it), but there is not enough RAM to keep all of those app proceses in cache, so the system ends up continually thrashing through processes each time the broadcast is sent.This is an issue regardless of whether the device is currently plugged in to power. In fact, this can more frequently be an issue on Android TV devices (which are always plugged in to power) because they tend to be fairly tight on RAM!
Certainly, there are plenty of system-sent implicit broadcasts that have lots of registered receivers. Years ago, I ran some code to count how many apps registered for ACTION_BOOT_COMPLETED, and an off-the-shelf device had 70-odd such receivers. Hence, when ACTION_BOOT_COMPLETED goes out, Android needs to fork 70-odd processes, create 70-odd receivers, and deliver 70-odd broadcasts. As a result, process lifetime tends to be fairly short, as Android needs to keep terminating processes to free up system RAM for yet more processes.
(ironically, ACTION_BOOT_COMPLETED is not affected by the ban, as while there are lots of registrants, that broadcast goes out infrequently)
WTF? (W = Who)
This affects:
Implicit broadcasts sent by the system, except for a handful of whitelisted ones and those that are actually explicit broadcasts that happen to have an action stringImplicit broadcasts sent by apps, intended to be delivered to other appsImplicit broadcasts sent by apps, intended to be delivered only to themselves, based off of old programming patterns that used system broadcasts instead of an in-process event bus (e.g., LocalBroadcastManager)
Most developers will worry most about the system-sent broadcasts, as those are numerous.
WTFW? (W = What’s and Workaround, Respectively)
If you are using broadcasts for communicating between app components within a single process, switch to using LocalBroadcastManager.
If you are using broadcasts for communicating between app components within multiple processes of your own, switch to using explicit broadcasts.
If you are receiving system-sent implicit broadcasts (e.g., ACTION_PACKAGE_ADDED), keep your targetSdkVersion at 25 or lower, until we figure out better workarounds that (hopefully) do not involve polling.
If you are sending implicit broadcasts, you can break through the ban by finding the receivers and sending individual explicit broadcasts instead:
private static void sendImplicitBroadcast(Context ctxt, Intent i) {
PackageManager pm=ctxt.getPackageManager();
List matches=pm.queryBroadcastReceivers(i, 0);
for (ResolveInfo resolveInfo : matches) {
Intent explicit=new Intent(i);
ComponentName cn=
new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName,
resolveInfo.activityInfo.name);
explicit.setComponent(cn);ctxt.sendBroadcast(explicit);
}
}
Unfortunately, this brings back the process churn, and if lots of developers do this, there may be reprisals from Google. You might try introducing some delay between the broadcasts, inside the loop, to spread out the impact. However, this starts to get tricky if you spread it out over more than a few seconds (e.g., do you now need an IntentService and a WakeLock? what if your process is terminated before the broadcast loop is completed?).
If you are receiving implicit broadcasts from another app, ask the developer of that app what the plan is for Android O. Perhaps they will use the above technique, or perhaps they will switch to some alternative communications pattern.
Find out about new posts on the CommonsBlog via the Atom feed, or follow @CommonsWare on Twitter!
— Apr 11, 2017 Tweet
Meta
Atom Feed@CommonsWare Twitter FeedOlder Posts
Copyright © 2017 CommonsWare, LLC — All Rights Reserved
- Background execution not allowed:
- Background Execution and Multitasking
- column not allowed here
- Method not allowed
- 405 Method Not Allowed
- 405 Method Not Allowed
- Method Not Allowed
- App op not allowed
- 405 (Method Not Allowed)
- inherited member not allowed
- 405 Method Not Allowed
- Method Not Allowed 405
- magento:DirectoryIndex not allowed here
- MYSQL HOST IS NOT ALLOWED
- Tomcat 405 Not Allowed nginx
- iis 405 Method Not Allowed
- 405 not allowed 解方法
- cursor:not-allowed 的使用
- IOCTL函数用法详解
- JQUERY AJAX请求成功,返回了数据,但是不进SUCCESS的问题
- LinuxC多线程详解
- Special Matrices
- JAVA教程到处都是 你知道如何学习JAVA编程吗
- Background execution not allowed:
- 链式物理结构(动态分配节点)
- 数据结构——顺序表
- SurfaceView相关概念的整理
- Java Web自定义MVC框架
- Java菜鸟学习日记36
- IntelliJ IDEA 当pom.xml更新时,自动加载pom.xml
- java乱码问题处理
- 华为OJ python实现