(三十三) Broadcast之有序广播





demo: jiatai 的 demo for ordered broadcast


1. 串行广播的简单demo

1.1 新建broadcastReceiver

package com.example.demo_33_broadcast_parallel;

import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;

public class BroadcastReceiverList {
    public static String TAG = "BroadcastReceiverList";
    public static class HighLevelBroadcastReceiver extends BroadcastReceiver{
         * This method is called when the BroadcastReceiver is receiving an Intent
         * broadcast.  During this time you can use the other methods on
         * BroadcastReceiver to view/modify the current result values.  This method
         * is always called within the main thread of its process, unless you
         * explicitly asked for it to be scheduled on a different thread using
         * {@link Context#registerReceiver(BroadcastReceiver, * IntentFilter, String, Handler)}. When it runs on the main
         * thread you should
         * never perform long-running operations in it (there is a timeout of
         * 10 seconds that the system allows before considering the receiver to
         * be blocked and a candidate to be killed). You cannot launch a popup dialog
         * in your implementation of onReceive().
         * <p>
         * <p><b>If this BroadcastReceiver was launched through a <receiver> tag,
         * then the object is no longer alive after returning from this
         * function.</b> This means you should not perform any operations that
         * return a result to you asynchronously. If you need to perform any follow up
         * background work, schedule a {@link JobService} with
         * {@link JobScheduler}.
         * <p>
         * If you wish to interact with a service that is already running and previously
         * bound using {@link Context#bindService(Intent, ServiceConnection, int) bindService()},
         * you can use {@link #peekService}.
         * <p>
         * <p>The Intent filters used in {@link Context#registerReceiver}
         * and in application manifests are <em>not</em> guaranteed to be exclusive. They
         * are hints to the operating system about how to find suitable recipients. It is
         * possible for senders to force delivery to specific recipients, bypassing filter
         * resolution.  For this reason, {@link #onReceive(Context, Intent) onReceive()}
         * implementations should respond only to known actions, ignoring any unexpected
         * Intents that they may receive.
         * @param context The Context in which the receiver is running.
         * @param intent  The Intent being received.
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "high level receiver");
            setResult(0, "high", null);

    public static class MidLevelBroadcastReceiver extends BroadcastReceiver{
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "middle level receiver-->getResultCode: " + getResultCode() + " getResultData: " + getResultData());
            setResult(1, "middle", null);

    public static class LowLevelBroadcastReceiver extends BroadcastReceiver{
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "low level receiver-->getResultCode: " + getResultCode() + " getResultData: " + getResultData());
            setResult(2, "low", null);


1. onReceive一般是运行在主线程中的

2. onReceive不支持耗时操作,需要控制在10s执行完成


1.2 注册BroadcastReceiver


        <receiver android:name=".BroadcastReceiverList$HighLevelBroadcastReceiver">
            <intent-filter android:priority="3000">
                <action android:name="com.jiatai.broadcast.ordered" />
        <receiver android:name=".BroadcastReceiverList$MidLevelBroadcastReceiver">
            <intent-filter android:priority="2000">
                <action android:name="com.jiatai.broadcast.ordered" />
        <receiver android:name=".BroadcastReceiverList$LowLevelBroadcastReceiver">
            <intent-filter android:priority="1000">
                <action android:name="com.jiatai.broadcast.ordered" />

1.3 发送有序广播

package com.example.demo_33_broadcast_parallel;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class BroadcastTestActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState) {
        Intent intent = new Intent("com.jiatai.broadcast.ordered");
        sendOrderedBroadcast(intent, null);

1.4 调试

1.5 试下有序广播拦截

1.6 用虚拟机调试

用虚拟机调试的时候如果没有指定包名,广播会被framework拦截下来不会传递到应用侧,结合广播在Android 8.0里的修改,如果是隐式广播,并且是静态注册的话,会大概率收不到广播。对应解决方法是对广播的intent设置对应的包名将其改为显示广播。(我试了下如果设置对应类名则会继续收不到广播,这是否意味着类名会限制只在对应类里接收么=-=)


“限制在AndroidManifest.xml中注册接收隐式广播,如ACTION_PACKAGE_REPLACED ,但也有些例外如ACTION_BOOT_COMPLETED,ACTION_LOCALE_CHANGED(所有例外参考文末连接)。(注意此部分限制都是只针对targetSdkVersion为android O,或者编译的SDK为android O及以上的的,低于的则不受影响)”


 else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
                            || (r.intent.getComponent() == null
                                && r.intent.getPackage() == null
                                && ((r.intent.getFlags()
                                        & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
                                && !isSignaturePerm(r.requiredPermissions))) {
                        Slog.w(TAG, "Background execution not allowed: receiving "
                                + r.intent + " to "
                                + component.flattenToShortString());
                        skip = true;
可以看出如果没有指定Component和Package则会将skip设为true, 至于源码中的flag是hide类型的,第三方中调用不到。
     * If set, the broadcast will never go to manifest receivers in background (cached
     * or not running) apps, regardless of whether that would be done by default.  By
     * default they will receive broadcasts if the broadcast has specified an
     * explicit component or package name.
     * @hide
    public static final int FLAG_RECEIVER_EXCLUDE_BACKGROUND = 0x00800000;

2. 总结


版权声明:本文为博主原创文章,转载请注明出处,O(∩_∩)O谢谢 https://blog.csdn.net/sinat_20059415/article/details/80296863
文章标签: 有序广播
个人分类: Android
想对作者说点什么? 我来说一句

Broadcast Demo

2017年03月23日 1.27MB 下载



(三十三) Broadcast之有序广播