咱們使用的上一屆的版本中,使用的底層的 安卓的 API 是 Android7.0 。在這一版本中,咱們將 API進行了升級,爲了更好的兼容新功能。(發送通知),咱們在升級 API中遇到的主要問題就是,在 Android7.0 到 Android8.0 這兩個版本之間的時候,安卓會禁用隱式的靜態廣播,至於什麼是安卓的廣播與廣播的機制,咱們推薦這篇博客,傳送門 。html
廣播主要用於 Android 中的不一樣進程之間的通訊。通常執行的操做主要是 喚醒,或者發送通知,啓動等等。java
廣播的主要工做流程是:android
1.廣播接收者BroadcastReceiver經過Binder機制向AMS(Activity Manager Service)進行註冊;api
2.廣播發送者經過binder機制向AMS發送廣播;app
3.AMS查找符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到BroadcastReceiver(通常狀況下是Activity)相應的消息循環隊列中;ui
4.消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法。code
安卓系統不斷地升級的過程當中,對廣播機制作了不少的改變,這是由於廣播的機制對資源的佔用與消耗。所以在 Android 不斷地升級的過程當中對這個廣播機制作出了更多的限制。component
不一樣Android API版本中廣播機制相關API重要變遷htm
1).Android5.0/API level 21開始粘滯廣播和有序粘滯廣播過時,之後再也不建議使用;blog
2).」靜態註冊的廣播接收器即便app已經退出,主要有相應的廣播發出,依然能夠接收到,但此種描述自Android 3.1開始有可能再也不成立「
Android 3.1開始系統在Intent與廣播相關的flag增長了參數,分別是FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES。
FLAG_INCLUDE_STOPPED_PACKAGES:包含已經中止的包(中止:即包所在的進程已經退出)
FLAG_EXCLUDE_STOPPED_PACKAGES:不包含已經中止的包
而在安卓的官方文檔中能夠看到 Android8.0 對廣播機制作出的更加嚴格限制:
可是有時候,咱們仍是想使用靜態廣播來發送提醒或者是在 APP 關閉的狀況下接收廣播。
突破隱式限制的方法就是發送廣播的時候攜帶intent.addFlags(0x01000000);
咱們看一下 Android8.0 的開源代碼,在1278行有一個 skip = true;
1267 } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0) 1268 || (r.intent.getComponent() == null 1269 && r.intent.getPackage() == null 1270 && ((r.intent.getFlags() 1271 & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0) 1272 && !isSignaturePerm(r.requiredPermissions))) { 1273 mService.addBackgroundCheckViolationLocked(r.intent.getAction(), 1274 component.getPackageName()); 1275 Slog.w(TAG, "Background execution not allowed: receiving " 1276 + r.intent + " to " 1277 + component.flattenToShortString()); 1278 skip = true; 1279 }
咱們想要進去的話,就不帶 FLAG_RECEIVER_INCLUDE_BACKGROUND 標誌位就能夠了,因而咱們設置
public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;