1. 广播机制

标准广播: 是一种完全异步执行的广播,在广播发出后几乎所有的接收器都会在同一时刻受到广播消息。因此它们之间没有任何的先后顺序,这种广播效率比较高,但同时意味着不能被截断。

有序广播: 是一种同步执行的广播,在广播发出后,同一时刻只有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后广播才会继续传播。有序广播是有先后顺序的,优先级高的会优先接受到广播并且可以截断正在传递的广播。

2. 接收系统广播

2.1 动态监听

动态监听网络变化

新建一个类,让他继承 BoradcastReceiver 并重写 onReceive() 方法,当接受到广播后就会执行 onReceive() 方法,这样一个简单的广播接收器就创建好了。

public class NetChangeActivity extends AppCompatActivity {

    NetWorkChangeReceiver netWorkChangeReceiver;
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ui);
        IntentFilter intentFilter = new IntentFilter(); 
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        netWorkChangeReceiver = new NetWorkChangeReceiver();
        registerReceiver(netWorkChangeReceiver,intentFilter);
    }

    class NetWorkChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"网络状态发生变化",Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(netWorkChangeReceiver);
    }
}

步骤:

  1. 新建一个广播接收器
  2. 通过 IntentFilter 来指定要接收的广播
  3. registerReceiver() 来注册广播
  4. 动态注册的广播接收器一定要取消注册

2.2 静态监听

静态监听实现开机自启

动态监听的缺点:动态注册的广播必须在程序启动后才能接收广播。

静态注册可以让程序没有启动就接受到广播消息。

首先我们新建一个 Java 类继承自 BroadcastReceiver

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"开机完成",Toast.LENGTH_SHORT).show();
    }
}
<application>  
   <receiver    android:name="com.example.firstcode.fifty_chapter.bootreceiver.BootCompleteReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
</application>
  • exported 为 true 表示可以接收本程序之外的广播。
  • enable 的意思就是启用这个广播接收器。

广播接收器 onReceive() 方法里面不要做太多的逻辑或者任何的耗时操作,因为在广播接收器中是不允许开启线程的,并且如果 onReceive() 方法运行了较长时间而没有结束的话程序就会报错。因此广播接收器扮演的是一种打开程序其他组件的角色,比如创建状态栏通知,或者启动一个服务等等。

3. 发送自定义广播

3.1 发送标准广播

首先需要定义一个广播接收器,与上类似,此处不在累述。

Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);

调用 context 的 sendBroadcast 即可发送广播,也可以通过 intent 携带数据。

3.2 发送有序广播

Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent, null);

为广播接收器定义优先级,优先级高的先接收到广播

<application>  
   <receiver 
        android:name="com.example.firstcode.BootCompleteReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter android:priority="100">
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
</application>

截断广播,不让广播继续传递

public class MyBroadReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"",Toast.LENGTH_SHORT).show();
        // 截断广播
        abortBroadcast();
    }
}

3.3 有序广播权限用法

谁有权接受我的广播

发送者

sendOrderedBroadcast(intent, "com.android.permission.yourdiyname");

AndroidManifest.xml 中声明权限, 注意要和上面的对应上

<permission android:name="com.android.permission.yourdiyname" />

接收者

AndroidManifest.xml中声明权限 注意要和上面对应上

<uses-permission android:name="com.android.permission.yourdiyname" />

只有全部对应上接收者才会接收到广播

谁有权给我发送广播

发送者

<uses-permission android:name="com.android.permission.yourdiyname" />

接收者

<permission android:name="com.android.permission.yourdiyname" />

<receiver android:name=".YourDiyReceiver" 
          android:permission="com.android.permission.yourdiyname"> 
	<intent-filter>
		 <action android:name="com.android.YOUR_DIY_ACTION" /> 
	</intent-filter>
</receiver>

4. 本地广播

本地广播机制使发出的广播只能在程序内部传递,并且广播接收器也只能接收来自本程序的广播,主要利用 LocalBriadcastManager 来对广播进行管理。

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;

    private LocalReceiver localReceiver;

    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取实例
        localBroadcastManager = LocalBroadcastManager.getInstance(this); 
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
                // 发送本地广播
                localBroadcastManager.sendBroadcast(intent); 
            }
        });
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        // 注册本地广播监听器
        localBroadcastManager.registerReceiver(localReceiver, intentFilter); 
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    class LocalReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
        }

    }

}
  1. 通过 LocalBroadcastManager.getInstance(this); 获取实例
  2. localBroadcastManager.sendBroadcast(intent); 发送本地广播
  3. localBroadcastManager.registerReceiver(localReceiver, intentFilter); 注册本地广播接收器