四大组件|Broadcast的基本用法

Android中每个应用进程都可以对自己感兴趣的广播进行注册,这些广播可以来自系统,也可以来自其他应用程序。接受广播可以轻松实现跨进程或应用内异步交流,比如App开机自启、App内强制下线。

  • 广播的种类
  • 接收广播
  • 发送自定义广播
  • 使用本地广播

广播的种类

  • 标准广播:

是一种完全异步执行的广播,广播发出后,所有注册该广播的接收器几乎在同一时刻接收到该广播,没有先后顺序。因为这种广播没有先后顺序,所以它的效率比较高,但也意味着它不能被截断。

  • 有序广播:

与标准广播相反,有序广播是一种同步的广播,广播发出后,同一时刻只有一个接收器接收到广播,且该接收器可以截断广播。此时广播是有先后顺序的。

接收广播

Android中有很多系统广播,我们可以在应用中监听这些广播获得系统的状态信息。如开机后发送一条信息,网络状态更改时发送一条信息等。

  • 动态注册:

在代码中注册,也就是需要打开应用程序才能注册接受器,可用于监听网络状态的变化等。

  1. 新建一个类继承BroadcastReceiver。
  2. 重写onReceive(),在方法中实现业务逻辑。
  3. 新建一个IntentFilter并添加action,action表示监听什么广播。
  4. 新建广播类实例。
  5. onCreate()注册,onDestroy()中注销。
    以下为监听网络状态实例:
public class BroadcastActivity extends AppCompatActivity {
    private NetworkReceive receive;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcast);
        //第三至第五步
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        receive = new NetworkReceive();
        registerReceiver(receive, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //第五步
        unregisterReceiver(receive);
    }
    
    //第一步
    class NetworkReceive extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            //第二步,由于该广播为监听网络状态,我们还要具体判断网络是否有连接
            ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isConnected()){
                Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

//AndroidManifest.xml中申请网络权限
    
  • 静态注册

虽然动态注册可以自由控制广播的注册与注销,但它一个缺点就是需要应用启动时才能接受广播。而静态注册可以在应用未启动时接收广播,可实现开机自启这一类的需求。

  1. 使用Android Studio提供的快捷方式新建Broadcast Receiver
  2. 在AndroidManifest.xml中注册广播
  3. 重写onReceive实现业务逻辑
  4. 声明需要的权限
    以下实现开机自启:
 //第一步,新建Receiver...
 //第二、四步,AndroidManiefest中
    //声明权限
     
    
    
            //静态注册
            
                
            
        
    
    
    //第三步
public class BootCompleteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        //实现业务逻辑
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
    }
}

两种注册均有优缺点,应结合使用。需要注册的是,不可在onRecevie()中添加过多的逻辑或者进行任何耗时操作。 因为广播接收器是不允许开启线程的。如果onReceive()执行了较长时间而没有结束,程序就会报错。因此,广播一般是一种打开程序其他组件的角色,如创建一条通知,启动一个服务等。

发送自定义广播

  • 发送标准广播:
    //activity中
    //构造函数传入action,接受广播需要这个action
    Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
    sendBroadcast(intent);

除此之外,还可以在Intent中携带一些数据传递到广播接收器中。

  • 发送有序广播
    //与标准广播类似
    Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
    sendOrderedBroadcast(intent, null);

第二个参数null表示与权限相关的字符串,这里传null就行。
有序广播的优先顺序,在AndroidManifest.xml中对应的receiver声明 android:priority即可,数值越大,优先级越高。

    
            
                
            
        
    

有序广播还可以截断广播,在接收器onReceive()中调用abortBroadcast()即可。

public class BootCompleteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        //实现业务逻辑
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
        abortBroadcast();
    }
}

使用本地广播

以上提到的都是属于系统全局广播,发出的广播可被系统任何一个应用接收到,这就容易引起安全性问题。因此,在本应用内传递数据,我们可以使用本地广播,本地广播其他应用无法接收,只允许本应用接收。
发送本地广播:

  1. 新建LocalBroadcastManager实例
  2. 新建Intent,与全局广播类似
  3. 通过LocalBroadcastManager发送Intent
    接受本地广播:
  4. 与全局广播类似,新建一个类继承BroadcastReceiver
  5. 添加IntentFilter
  6. 通过LocalBroadcastManager动态注册与注销
public class BroadcastActivity extends AppCompatActivity {
    private LocalReceive receive;
    
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broadcast);
        
        //第一步
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        //第二、三步
        Intent intent = new Intent("com.example.learnapplication.LOCAL_BROADCAST");
        localBroadcastManager.sendBroadcast(intent);
        
        //第五、六步
        receive = new LocalReceive();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.learnapplication.LOCAL_BROADCAST");
        localBroadcastManager.registerReceiver(receive, intentFilter);
    }

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

    //第四步
    class LocalReceive extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            //处理具体逻辑
            Toast.makeText(context, "receive local broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}

需要强调的是,本地广播接收器不能静态注册,且发送本地广播比发送全局广播更加高效。本地广播通常用于实现本应用全局通知,如强制下线、推送等。 结合之前Activity的BaseActivity用法,可实现应用内全局接收广播并做出响应。

参考:
《第一行代码》

你可能感兴趣的:(四大组件|Broadcast的基本用法)