Android 四大组件 BroadcastReceiver 深入剖析注册与使用!

BroadcastReceiver

作为 Android 的四大组件之一 BroadcastReceiver 有着非常广泛的使用。要想使用 BroadcastReceiver 搜先高搞明白 Broadcast 目前来看, Broadcast 也就是所谓的广播,主要分为两种:普通广播 和 有序广播。故名思意,Broadcast 就是用于发出消息,而 BroadcastReceiver 则是用来接收消息。


普通广播

就是能让所有的 BroadcastReceiver 都接收到消息,这样咋一看非常方便,但实际上有个很严重的缺陷,就是信息不能被一层层的广播,按照优先级(-1000 - 1000)次序接收,包装、在传递。

有序广播

有序广播,顾名思义,与普通广播相比,就是增添了有序性。也就是它能够一层层的包装并向下传播。所以它也就克服了 普通广播 致命的缺点。


广播发送

方法一:Context.sendBroadcast

这就是普通广播的发送方法,也就是让所有接收器都收到广播

方法二:Context.sendOrderedBroadcast

  • 这个方法发送的是有序广播,系统会根据声明的优先级,按顺序逐个执行 BroadcastReceiver ,前面的接收者有权终止广播(调用 BroadcastReceiver.abortBroadcast()),注意:广播被前面的接收者终止,后面的接收者就再也无法获取到广播。
  • 对于有序广播,前面的接收者可以将处理结果通过setResultExtras(Bundle)方法存放进结果对象,然后传给下一个接收者,通过代码:Bundle bundle =getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据。
  • 系统收到短信,发出的广播属于有序广播。如果想阻止用户收到短信,可以通过设置优先级,让你们自定义的接收者先获取到广播,然后终止广播,这样用户就接收不到短信了。


生命周期:

广播的生命周期非常短暂,如果一个广播处理完 onReceive 方法,那么系统将认定此广播对象,不再是一个活动的对象。这时候它就会 finish 掉它。
拓展:同时还有一个注意点,我们知道,既然 BroadcastReceiver 生命,周期这么短暂,就不应该用它来做一些耗时操作( 更 普通的 Service 一样 ),就是说不要在里边定义线程,用 sleep 方法等。


BroadcastReceiver 步骤:

1,自定义一个类继承 BroadcastReceiver
2,重写 onReceive 方法
3,在 manifest.xml 中注册 ( 但不注册好像也没事。。。主要是为了安全 )

MyBroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {

    private int progressStatus = 0;
    private final String EXTRA_ID = "status";

    private ProgressDialog progressDialog;

    MyBroadcastReceiver(){

    }

    public MyBroadcastReceiver(ProgressDialog progressDialog){
        this.progressDialog = progressDialog;
    }

    // 回调判断意图 更新进度条
    @Override
    public void onReceive(Context context, Intent intent) {
        // 。。。
    }
}

重写 onReceive

我在这里模拟了一个进度条,接收到信息后 更新 进度条信息,进度条在广播注册时被传入

    // 回调判断意图 更新进度条
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null){
            switch (intent.getAction()){
                case IntentManager.ACTION_TYPE_SERVICE:
                    progressDialog.setMessage("线程状态:" + intent.getStringExtra(IntentManager.INTENT_STATUS_SERVICE));
                    if (intent.getStringExtra(IntentManager.INTENT_STATUS_SERVICE).equals("服务已结束运行")){
                        progressDialog.dismiss();// 从源码看出调用后 在调用了 dismiss()
                    }
                    break;

                case IntentManager.ACTION_TYPE_THREAD:
                    progressStatus = intent.getIntExtra(IntentManager.INTENT_PROGRESS_SERVICE, 0);
                    progressDialog.setMessage("线程状态:" + intent.getStringExtra(IntentManager.INTENT_STATUS_SERVICE));
                    progressDialog.setProgress(progressStatus);
                    break;
            }
            progressStatus = intent.getIntExtra(EXTRA_ID, 0);
        }else {
            // ...
        }
    }

在 manifest.xml 中注册

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        。
        。
        。
        <receiver android:name=".broadcast.MyBroadcastReceiver">
            <!--这里自定义一个广播动作-->
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="test"/>
            </intent-filter>
        </receiver>
    </application>

并在 Mainfest.xml 中添加权限

    <uses-permission android:name="android.permission.INTERNET" /> <!-- 广播权限 -->

上面完成了广播基本功能的实现,现在我们在活动里来实现具体的

注册广播:

注册很简单

  1. 定义 LocalBroadcastManager 类对象
  2. 实例化一个 MyBroadcastReceiver 对象,并将需要更新的控件传入
  3. 实例化 intentFilter 对象,并给他添加 action
  4. 调用 registerReceiver 进行注册
    private fun iniBroadCast() {
        val manager = LocalBroadcastManager.getInstance(this)
        val broadcastReceiver = MyBroadcastReceiver(progressDialog)// 在这之前 progressDialog 要先被实例化出来
        val intentFilter = IntentFilter()
        intentFilter.addAction(IntentManager.ACTION_TYPE_SERVICE)
        intentFilter.addAction(IntentManager.ACTION_TYPE_THREAD)
        manager.registerReceiver(broadcastReceiver, intentFilter)
        val intent = Intent(this, MyIntentService::class.java)
        startService(intent)
    }

发送广播

  1. 建立一个 Intent 添加 Action 
  2. 用 putExtra 传入信息
  3. 调用 sendBroadcast 发送
        manager = LocalBroadcastManager.getInstance(this);
    private void sendIfoToBroadCast(String serviceStatus){
        Intent intent1 = new Intent(IntentManager.ACTION_TYPE_SERVICE);
        intent1.putExtra(IntentManager.INTENT_STATUS_SERVICE, serviceStatus);
        manager.sendBroadcast(intent1);
    }

    private void sendIfoToBroadCast(String serviceStatus, int progressStatus){
        Intent intent = new Intent(IntentManager.ACTION_TYPE_THREAD);
        intent.putExtra(IntentManager.INTENT_STATUS_SERVICE, serviceStatus);
        intent.putExtra(IntentManager.INTENT_PROGRESS_SERVICE, progressStatus);
        manager.sendBroadcast(intent);
    }

这里有个注意点 -> https://blog.csdn.net/qq_43377749/article/details/90738979

静态注册与动态注册

静态注册:

        MyBroadcastReceiver myBroadcastReceiver=new MyBroadcastReceiver();
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction("com.example.dimple.MY_BROADCAST");
        registerReceiver(myBroadcastReceiver,intentFilter);

在用完后 记得及时接触注册

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myBroadcastReceiver);
    }  
  • 静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

动态注册:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"开机启动!",Toast.LENGTH_LONG).show();
    }  
} 

 添加权限:

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

 在 Mainfest 中注册

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        。
        。
        。
        <receiver android:name=".broadcast.MyBroadcastReceiver">
            <!--这里自定义一个广播动作-->
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="test"/>
            </intent-filter>
        </receiver>
    </application>
  • 动态注册广播不是常驻型广播,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。

文中代码 Demo 已打包到 github 点击跳转->

点击跳转 https://github.com/FishInWater-1999/android_four_major_components

如果觉得我归纳的还行,不妨点个赞呦~么么哒~~

猜你喜欢

转载自blog.csdn.net/qq_43377749/article/details/90739370