Android8.0的新特性值得注意一下,不然会出现很多莫名的问题。。。
Android 8.0 为提高电池续航时间而引入的变更之一是,当您的应用进入已缓存状态时,如果没有活动的组件,系统将解除应用具有的所有唤醒锁。
此外,为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:
默认情况下,这些限制仅适用于针对 O 的应用。不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。
Android 8.0 还对特定函数做出了以下变更:
startService()
函数,则该函数将引发一个 IllegalStateException
。Context.startForegroundService()
函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用 Context.startForegroundService()
。不过,应用必须在创建服务后的五秒内调用该服务的 startForeground()
函数。
以下这个就是Android8.0的后台限制新特性导致的,果然要踩过坑,才印象深刻。
自己编写了一个demo跟踪广播的发送流程。
demo:注册一个静态receiver,然后发送广播。
Activity中发送广播的代码:
public class MainActivity extends Activity {
public static final String TAG = "TEST";
public final String TEST_ACTION = "com.maureen.test.TEST_ACTION";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume");
Log.d(TAG,">>sendBroadcast");
Intent intent = new Intent(TEST_ACTION);
sendBroadcast(intent);
Log.d(TAG,"<
Receiver对应的java文件:
public class MyTestReceiver extends BroadcastReceiver {
private final String TAG = "TEST-MyTestReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"Static receiver:action=" + intent.getAction());
}
}
好的,现在开始运行这个demo。结果这个receiver一直都没有收到广播。。。。。
查看log,发现了warning信息:
W BroadcastQueue: Background execution not allowed: receiving Intent { act=com.maureen.test.TEST_ACTION flg=0x10 } to com.example.atc6111.testswitchicon/.MyTestReceiver
"Background execution not allowed" 打印出该warning的代码:
即是以下两种情况静态receiver不会接收到广播:
①intent没有指定接收组件,也就是没有setComponent
②intent没有执行接收的package,也就是没有setPackage
③发送的intent没有设置FLAG-FLAG_RECEIVER_INCLUDE_BACKGROUND
④给定的权限并不都是签名权限。
根据这两种情况,即是说静态receiver接收不了隐式广播。本来打算采用最简单的方法添加Flag来解决的。
但是奇怪的是,Android Studio里没有FLAG_RECEIVER_INCLUDE_BACKGROUND!!!!
然后,只好在发送intent的时候setPackage。
@Override
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume");
Log.d(TAG,">>sendBroadcast");
Intent intent = new Intent(TEST_ACTION);
intent.setPackage(getPackageName());
sendBroadcast(intent);
Log.d(TAG,"<
修改之后,静态Receiver就能收到广播了。
但是如果就是想让静态receiver接收到隐式广播呢?应该还有其他方法,待学。。。。