《Android第三章》广播Broadcast Receiver

 《Android第一行代码》书本记录

 

Broadcast Receiver类型:

  • 标准广播(无序广播):是一种完全异步执行的广播,在广播发出后,所有广播接收器几乎会同时接收到这个广播消息,因此没有先后顺序可言,这种广播的效率比较高,同时意味着无法截断.
  • 有序广播:是一种同步执行的广播,在广播发出后,同一个时刻只有一个广播接收器能接收到,当这个广播接收器中的逻辑执行完广播才会传递.所有此时的广播接收器是由先后顺序的,优先级高的广播接收器可以先接收,并且前的广播接收器可以截断正在传递的广播,这样后面的广播接收器就无法接收信息.

 

Broadcast Receiver注册方式:

  • 动态注册:在代码中注册
  • 例子:
动态注册监听网络变化:
public class MainActivity extends AppCompatActivity {

    private NetWorkChangeReceiver netWorkChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//设置意图 IntentFilter intentFilter
=new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//创建广播接收器 netWorkChangeReceiver
= new NetWorkChangeReceiver();
//注册广播 registerReceiver(netWorkChangeReceiver,intentFilter); }
public class NetWorkChangeReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(MainActivity.this, "网络发生了变化", Toast.LENGTH_SHORT).show(); } } @Override protected void onDestroy() { super.onDestroy(); //动态注册记得取消广播注册 unregisterReceiver(netWorkChangeReceiver); } }
  • 静态注册:要在AndroidManifest.xml文件注册
  • 例子:
静态注册实现开机启动例子:

AndroidManifest.xml文件里需要注册:

增加权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

注册
 <receiver
            android:name=".MainActivity$NetWorkChangeReceiver"
            android:enabled="true"
            android:exported="true"
            >
            <intent-filter >
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
 </receiver>

编写广播类:
public class BootCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "开机完成", Toast.LENGTH_SHORT).show();
}
}
  • 注意:不要在onReceive()方法执行过多逻辑或者进行任何耗时操作,因为在广播接收器中是不允许开启线程的,当onRecevie()方法运行了较长时间而没有结束时,程序就会报错。
  •  因此广播接收器扮演的角色大多数都是打开程序或者其他组件角色,比如创建一条状态栏通知,或者启动一个服务等.

 


发送自定义广播:

  • 发送标准(无序)广播:
  • 发送广播前先定义一个广播接收来接收广播来测试,不然白发:
       public class MyBroadcastReceiver extends BroadcastReceiver{
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(MainActivity.this, "接收到广播", Toast.LENGTH_SHORT).show();
            }
        }
    
    然后AndroidManifest.xml注册广播:
    <receiver
                android:name=".MainActivity$MyBroadcastReceiver"
                android:enabled="true"
                android:exported="true"
                >
                <intent-filter >
                    <action android:name="android.intent.broadcasttest.MY_BROADCAST"/>
                </intent-filter>
     </receiver>
    
    
    然后设置一个按钮发送广播,action设置为android.intent.broadcasttest.MY_BROADCAST:
    
       public void sendBroadcast(View view){
            Intent intent=new Intent("android.intent.broadcasttest.MY_BROADCAST");
            sendBroadcast(intent);
    
        }
    
    点击按钮就能接收到广播的了
  •  发送有序广播:
  • 发送广播前先定义一个广播接收来接收广播来测试,不然白发:
       public class MyBroadcastReceiver extends BroadcastReceiver{
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(MainActivity.this, "接收到广播", Toast.LENGTH_SHORT).show();
    //abortBroadcast()如果调用这个方法表示截断广播 } }
    然后AndroidManifest.xml注册广播,注意这里多了一个属性android:priority,这里就是设置优先级,数越大优先级越高
    <receiver android:name=".MainActivity$MyBroadcastReceiver" android:enabled="true" android:exported="true" > <intent-filter android:priority="100" > <action android:name="android.intent.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver> 然后设置一个按钮发送广播,action设置为android.intent.broadcasttest.MY_BROADCAST: public void sendBroadcast(View view){ Intent intent=new Intent("android.intent.broadcasttest.MY_BROADCAST"); sendOrderedBroadcast(intent,null); } 发送有序广播只需要修改一行代码即可,把sendBordcast换成sendOrderedBroadcast即可,
    sendOrderedBroadcast第一个参数为intent,第二个参数为null,这是关于一个权限的参数,填NUll即可

 

 

本地广播:

  • 前面我们发送和接收的广播全部属于系统全局广播,即发出的广播能被其他任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样很容易引起安全问题,为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制,这个机制发出的广播只能够在应用程序内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播。
  • 例子
  • 本地广播的用法并不复杂,主要使用了LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法:
    
    public class MainActivity extends AppCompatActivity {
    
          private LocalBroadcastManager localBroadcastManager;
    
          private LocalReceiver localReceiver;
    
            @Override
    
            protected void onCreate(Bundle savedInstanceState){
    
               super.onCreate(savedInstanceState);
    
               setContentView(R.layout.activity_main);
    
               localBroadcastManager=LocalBroadcastManager.getInstance(this);
    
               IntentFilter intentFilter=new IntentFilter();
    
               intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
    
               localReceiver=new LocalReceiver();
    
               localBroadcastManager.registerReceiver(localReceiver,intentFilter);
    
    }
    
    public void sendLocalBroadcast(View view){
    
     //点击按钮发送广播
    
             Intent intent=new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
    
             localBroadcastManager.sendBroadcast(intent);//发送本地广播
    
    }
    
    销毁时取消注册广播:
    
    @Override protected void onDestroy() {
    
         super.onDestroy();
    
         localBroadcastManager.unregisterReceiver(localReceiver);
    
    }
    
    广播接收器:
    
    class LocalReceiver extends BroadcastReceiver{
    
           @Override
    
           public void onReceive(Context context, Intent intent) {
    
              Toast.makeText(MainActivity.this,"本地广播",Toast.LENGTH_SHORT).show();
    
          }
    
         }
    
       }

     

两者及其接收广播的区别:

(1)动态注册广播不是常驻型广播,也就是说广播跟随Activity的生命周期。注意在Activity结束前,移除广播接收器。

          静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

(2)当广播为有序广播时:优先级高的先接收(不分静态和动态)。同优先级的广播接收器,动态优先于静态

(3)同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。

(4)当广播为默认广播时:无视优先级,动态广播接收器优先于静态广播接收器。同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后册的

posted @ 2021-06-28 11:44  白晨里的影子  阅读(106)  评论(0)    收藏  举报