Android 四大组件之 BroadcastReceiver

如何用Deep OC-SORT提升多目标跟踪精度?实战配置与性能优化指南 本文是一份针对开发者的Deep OC-SORT多目标跟踪实战指南。详细解析了如何通过部署其核心的“动态外观记忆”与“相机防抖”模块来有效应对遮挡与抖动,从而显著提升跟踪精度与连续性。内容涵盖从环境搭建、参数调优到性能压榨的全流程,并提供针对不同场景的配置建议与工程落地技巧。 阅读详情

       广播接受器( BroadcastReceiver)是 Android 的四大组件之一,Android 中的广播机制是非常灵活的,Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接受自己关心的广播内容,这些广播可能是来自系统的,也可能是来自其他程序的,Android 提供了一套完整的 API,允许应用程序间自由地接受和发送广播,今天我们来一起总结 Broadcast Receiver 的基本用法,我们先来列个大纲,让大家一目了然今天分享的内容




一、广播的机制简介


       在 Android 系统中,广播体现在方方面面,是 Android 的四大组件之一,是一个全局的监听器,用于监听和接受应用发出的广播消息,并作出相应的响应,在不同组件之间通信,系统特定情况下的通信,例如当开机完成后系统会产生一条广播,接受到这条广播就能实现开机启动服务的功能、当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示以及保存需要保存的数据等操作、当电池电量发生改变时,系统也会发出一条广播等等这些应用场景都有使用

广播主要的两种类型:标准广播 和 有序广播

       标准广播(Normal Broadcasts):是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎同时在统一时刻接受到这条广播消息,因此他们之间没有任何先后顺序而言,这种广播的效率比较高,但同时也意味着它是无法被截断的,标准广播的工作流程如下图:



接下来我们通过代码来验证一下,这里我们新建一个 BroadcastReceiver 项目来演示:


1)首先我们创建 MyReceiver 类并继承 BroadcastReceiver


public class MyReceiver extends BroadcastReceiver {

    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        throw new UnsupportedOperationException("Not yet implemented");
    }
}

        我们可以看到 MyReceiver 继承自 BroadcastReceiver,说明这是一个广播,广播里基本什么也没有,只有一个空的构造方法,和一个 onReceive() 方法,这个 onReceiver() 方法就是负责在接收到广播以后根据 Intent 携带来的数据来处理相关的逻辑的,创建完 MyReceiver 之后我们还没有能够使广播进入工作状态,我们还需要注册一个指定的广播地址,注册广播有两种方式:在代码中注册和在 AndroidManifest.xml 中注册,其中前者被称为动态注册,后者被称为静态注册

静态注册:

静态注册就是在 AndroidManifest.xml 中配置的,如下:

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

       配置了以上信息后,只要是 android.intent.action.MY_BROADCAST 这个地址的广播,MyReceiver 就都能接收得到,还需要注意的就是这种注册的方式是常驻型的,比较浪费内存

动态注册:

MyReceiver receiver = new MyReceiver();  
          
IntentFilter filter = new IntentFilter();  
filter.addAction("android.intent.action.MY_BROADCAST");  
          
registerReceiver(receiver, filter);
       动态注册需要在代码中动态的进行相关配置,上面就是我们的注册示范代码,registerReceiver 是 android.content.ContextWrapper 类中的方法,其实 Activity 和 Service 都继承了 ContextWrapper,所以可以直接调用在实际应用中,还有需要注意的就是,在 Activity 和 Service 中注册一个 BroadCastReceiver,当 Activity 和 Service 销毁的时候要记得在 onDestroy() 方法中解除

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

好了 说完了注册的两种常用注册类型,接下来我们继续来验证我们的标准广播的接受情况:

刚才我们已经创建好了自己的 MyReceiver 广播接收器,并且进行了注册,现在我们来发送一条广播,看会发生什么:

    public void sendMessage(View view) {
        Intent intent = new Intent("android.intent.action.MY_BROADCAST");
        intent.putExtra("msg", "hello receiver.");
        sendBroadcast(intent);
    }

       这里我们发送了一条广播,注意 sendBroadcast 也是 ContextWrapper 类中的方法,它可以将一个指定地址和参数信息的 Intent 对象以广播的形式发送出去,这里我们点击发送按钮,,看日志的打印情况:


      这里我们看到我们成功的接收到了广播,这里我们只是演示了一个接受者来接受广播,那么如果是多个会怎么样那,接下来我们来新建 3 个广播接受者,看看会是什么情况:

这里我们创建 First、Second、Third 三个接收器来接收广播如下:

public class First extends BroadcastReceiver {
    private static final String TAG = "First";

    public First() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "onReceive: " + msg);
    }
}

public class Second extends BroadcastReceiver {
    private static final String TAG = "Second";

    public Second() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "onReceive: " + msg);
    }
}

public class Third extends BroadcastReceiver {
    private static final String TAG = "Third";
    public Third() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "onReceive: "+msg);
    }
}

接下来大家别忘了注册,这里我就先采用在 AndroidManifest.xml 中进行注册了:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qiudengjiao.broadcastreceiver">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".First"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".Second"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".Third"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

        </receiver>
    </application>

</manifest>

这时候点击刚才发送广播的按钮,来看日志的打印情况:



       这里我们看到我们注册的接受者都接收到了发出的广播,接下来大家注意了,我们在 onReceive() 方法中添加 abortBroadcast() 来看是否能截断广播,如下,这里我们只贴出 First 中的代码,其他的也类似:

public class First extends BroadcastReceiver {
    private static final String TAG = "First";

    public First() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "onReceive: " + msg);
        abortBroadcast();
    }
}

这时候我们再来点击发送按钮看日志打印情况:



       日志我们截取了部分,可以看到我们仍然接收到了广播,并没有截断我们所发出的广播,大家都接收到了发出的广播,这说明保准广播是无法拦截的,报的错误告诉我们,在无序广播中使用拦截是错误的,当然我们这里只是演示,到这里我们就把标准广播分析完了,接下来我们来分析有序广播


       有序广播(Ordered Broadcast):是一种同步执行的广播,在广播发出之后同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的接收器就无法收到广播消息了,有序广播的工作流程如下图:


我们来修改一下 3 个接收者的代码:

public class First extends BroadcastReceiver {
    private static final String TAG = "First";

    public First() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.i(TAG, "onReceive: " + msg);

        Bundle bundle = new Bundle();
        bundle.putString("msg", msg + "...First...");
        setResultExtras(bundle);
    }
}

public class Second extends BroadcastReceiver {
    private static final String TAG = "Second";

    public Second() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = getResultExtras(true).getString("msg");
        Log.i(TAG, "onReceive: " + msg);

        Bundle bundle = new Bundle();
        bundle.putString("msg", msg + "...Second...");
        setResultExtras(bundle);
    }
}

public class Third extends BroadcastReceiver {
    private static final String TAG = "Third";

    public Third() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = getResultExtras(true).getString("msg");
        Log.i(TAG, "onReceive: " + msg);
        Bundle bundle = new Bundle();
        bundle.putString("msg", msg + "...Third...");
        setResultExtras(bundle);
    }
}

       这里我们为了标记顺序,在 First 和 Second 中都使用了setResultExtras 方法将一个 Bundle 对象传递到下一个接受者哪里,这样以来优先级低的可以用 getResultExtras() 方法获取到最新处理过的信息集合,这里的代码完成后我们需要在 AndoridMainfest.xml 文件中修改广播的优先级:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qiudengjiao.broadcastreceiver">

    <uses-permission android:name="scott.permission.MY_BROADCAST_PERMISSION" />
    <permission
        android:name="scott.permission.MY_BROADCAST_PERMISSION"
        android:protectionLevel="normal" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="997">
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".First"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".Second"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".Third"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="998">
                <action android:name="android.intent.action.MY_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

        </receiver>

    </application>

</manifest>

       这里我们看到我们在广播接受者的 <intent-filter> 标签里增加了 android:priority="" 这个属性,这个属性的使用范围在 -1000--1000 之间,数值越大优先级越高,接下来我们来修改一下发送广播的代码:

    public void sendMessage(View view) {
        Intent intent = new Intent("android.intent.action.MY_BROADCAST");
        intent.putExtra("msg", "hello receiver.");
        sendOrderedBroadcast(intent,"scott.permission.MY_BROADCAST_PERMISSION");
    }

       这里需要注意的是,使用 setOrderedBroadcast() 方法发送有序广播时,需要一个权限参数,如果为 null 则表示不要求接受者声明指定的权限,如果不为 null,则表示接受者若要接受此广播,需要声明指定权限,这是从安全角度来考虑的,例如系统的短信就是有序广播的形式,一个应用可能是具有拦截短信的功能,当短信到来时可以先接收到短信广播,必要时终止广播传递,这样的软件就必须声明接收短信的权限,所以我们在 AndroidMainfest.xml 中定义一个权限:

    <permission
        android:name="scott.permission.MY_BROADCAST_PERMISSION"
        android:protectionLevel="normal" />

然后声明使用此权限:

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


然后我们点击按钮发送一条广播,看控制台的打印情况:


       我们看到是按照优先升级的顺序打印的,从优先级搞得到优先级低的,既然是顺序传递,这里我们就能来截断,这次我们在 First 的广播中的 onReceive() 方法中加入如下代码:

        abortBroadcast();

点击发送广播按钮,我们来看看打印情况:


这里看到我们成功拦截了继续向下传递的广播,只有第一个接受到了我们的广播

上面这些基本的概念掌握以后,就下来我们就来看一下广播的其他用法吧,我们从系统广播开始


二、系统广播


       Android 内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种系统的状态信息,比如向我们文章开头说的,手机开机完成后会发出一条广播,电池的电量发生变化时会发出一条广播,时间和时区发生变化时也会发出一条广播,等等,接下来我们就来看一下它的具体用法结合我们上面学到的广播基本知识


1)动态注册监听网络变化


现在我们通过一个完整的动态注册广播的例子来巩固我们刚才学到的广播的基本使用,这时我们来修改 MainActivity 中的代码如下:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private IntentFilter intentFilter;

    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 实例
        netWorkChangeReceiver = new NetWorkChangeReceiver();

        //调用registerReceiver()方法进行注册
        registerReceiver(netWorkChangeReceiver, intentFilter);
    }

    /**
     * 内部类 NetWorkChangeReceiver
     */
    class NetWorkChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            //此处写逻辑
            Toast.makeText(context, "网路发生变化", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * 切记要在此进行取消注册
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册
        unregisterReceiver(netWorkChangeReceiver);
    }
}

       可以看到我们在 MainActivity 中定义了一个内部类 NetworkChangeReceiver,并继承自 BroadcastReceiver,重写了 onReceive() 方法,这样当网络状态发生变化时,我们提示了一个 Toast 文本信息,然后我们在 onCreate() 方法中我们创建了 IntentFilter 实例,并且添加了一个值为 android.net.conn.CONNECTIVITY_CHANGE 的 action,添加这个主要是因为,当网络发生变化时,系统发出的正是一条为 android.net.conn.CONNECTIVITY_CHANGE 的广播,也就是说我们的广播接收器想要监听什么,就得在这里添加相应的 action,接下来我们创建 NetworkChangeReceiver 的实例,然后调用 registerReceiver() 方法进行注册,将 NetworkChangeReceiver 和 IntentFilter 的实例都传进去,这样 NetworkChangeReceiver 就会收到 android.net.conn.CONNECTIVITY_CHANGE 的广播,也就实现了监听网络的功能,最后一定要记得在 onDestroy() 中通过 unregisterReceiver() 方法进行取消注册

这时候我们把程序运行起来,并按下 Home 键,注意不能按 back 键,那样程序会被杀死,接着我们来关闭打开网络设置,会看到,不停地弹出网络设置变化,到这里我们一个整体的动态网络注册监听网络变化的系统广播过程就完了


2)静态注册实现开机启动

       上面实现了完整的动态注册过程演示,动态注册的广播接收器可以自由的控制注册与注销,在灵活性方面有很大的优势,但是也有它的缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在 onCreate() 方法中的,那么动态注册就能实现在程序未启动的情况下接收到广播,接下来我们来进行一个完整的静态注册完整的演示:

我们新创建一个广播 BootCompeteReceiver 在创建界面的过程中,Exported 属性表示是否允许这个广播接收器接受本程序以外的广播,Enabled 表示是否启用这个广播接收器,完成创建如下:

public class BootCompleteReceiver extends BroadcastReceiver {

    public BootCompleteReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
    }
}

       代码非常简单,我们只是在 onReceive() 方法中提示一段信息,由于 Android Studio 的智能性 在 AndroidMainfest.xml 中的注册也被自动的创建好了:

        <receiver
            android:name=".BootCompleteReceiver"
            android:enabled="true"
            android:exported="true">

        </receiver>

        enabled 和 exported 则是我们刚才提到的属性,不过到这里,广播接收器还是不能接收开机广播的,我们还需要对 AndroidMainfest.xml 文件进行修改,如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qiudengjiao.broadcastreceiver">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        
        <receiver
            android:name=".BootCompleteReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                
            </intent-filter>

        </receiver>
    </application>

</manifest>

       由于 Android 系统启动后会发出一条值为 android.intent.action.BOOT_COMPLETED 的广播,因此我们在 <intent-filter> 标签里添加了相应的 action,另外,监听系统开机广播也是需要声明系统权限,可以看到我们也进行了相应权限的声明,接下来我们从新运行程序,启动完成后就能接收到开机广播了,到这里我们就把整个静态注册走了一遍,最后在真正的项目使用过程中,我们需要特别注意,不要在 onReceive() 方法中进行耗时的操作,因为广播接收器中是不允许开启线程的,当 onReceive() 方法运行了较长时间而没有结束时,程序就会报错,因此广播接收器扮演的更多的是一种打开程序其他组件的角色,比如创建一条通知栏,启动一个服务等


三、自定义广播


上面我们介绍了接收来自系统的广播,接下来我们来看看如何在应用程序中发送自定义广播,这里我们需改 MyReceiver 中的代码如下:

public class MyReceiver extends BroadcastReceiver {

    private static final String TAG = "MyReceiver";

    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "收到广播", Toast.LENGTH_LONG).show();
    }
}

MyReceiver 接收到自定义广播时会弹出传过来的数据,然后在 AndroidMainfest.xml 文件中对这个广播接收器进行修改:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qiudengjiao.broadcastreceiver">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcasttest.MY_BROADCAST" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

       可以看到我们让广播接收器接受一条 com.example.broadcasttest.MY_BROADCAST 的广播,因此待会儿发送广播的时候我们就需要发送对应的广播如下:

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void sendMessage(View view){
        Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
        sendBroadcast(intent);
    }
}

可以看到我们在点击按钮时加入了发送自定义广播的逻辑:

接下来我们点击按钮来看发送情况:




这里我们就成功实现了一个自定义的标准广播


四、本地广播


       前面我们发送和接收的广播全部属于系统全局广播,即发出的广播可以被其他任何应用程序接收到,并且我们也可以接收其他应用程序的广播,这样就很容易引起安全问题,例如我们发送一些携带关键数据的广播,有可能被其他应用程序截获,或者其他应用程序不停地向我们的应用程序的广播接收器里发送各种垃圾广播,为了能够简单的解决广播的安全问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全问题就解决了

       本地广播并不复杂,主要是使用了一个 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法,下面我们通过实例来进行讲解

修改 MainActivity 中的代码如下:

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 = LocalBroadcastManager.getInstance(this);
        //创建IntentFilter实例
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        //注册本地广播监听器
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);

    }

    public void sendMessage(View view) {
        Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
        //发送本地广播
        localBroadcastManager.sendBroadcast(intent);
    }

    class LocalReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "收到本地广播", Toast.LENGTH_LONG).show();
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
}

       看到上面的代码我们应该很熟悉了,和我们之前学到的动态注册是基本一样的,只不过这里通过 LocalBroadcastManager 的 getInstance() 方法得到了它的一个实例,然后在注册广播接收器的时候调用的是 LocalBroadcastManager 的 registerReceiver() 方法,同样在发送广播的时候调用的是 LocalBroadcastManager 的 sendBroadcast() 方法,仅此而已,我们来点击发送按钮看看我们是否接收到了这条广播:




我们看到成功的接收到了发出的广播,接下来我们来看使用本地广播的几点优势:

1.可以明确的知道发送的广播不会离开我们的程序,因此不必担心数据泄露问题

2.其他的程序无法将广播发送到我们的程序内部,因此不必要担心会有安全漏洞的隐患

3.发送本地广播比发送全局广播更加的高效


到这里几天今天我们分享的内容就基本完了,这里我们基本就把常用的广播都介绍了,如有错误请指出

参考:郭神第一行代码



Matlab实战:12种优化算法在CEC2014测试集上的性能对比(附完整代码) 本文详细对比了12种优化算法在CEC2014测试集上的性能表现,包括PSO、DE、GA等主流算法。通过Matlab实现完整的实验流程,涵盖算法实现、参数设置、结果分析与可视化,为工程优化问题提供实用解决方案。特别关注收敛曲线和评价指标,帮助读者选择最适合特定场景的优化算法。 阅读详情

相关推荐

GraphRAG 踩坑记录

GraphRAG踩坑记录

yufanwenshu的博客 4351

BroadcastReceiver

广播接收者什么是广播什么是BroadcastReceiver项目中使用广播广播生命周期广播分类使用BroadcastReceiver1.自定义类继承BroadcastReceiver,重写onReceive 什么是广播 生活中的广播大家都知道吧,就像村里的大喇叭,只要喇叭一放音乐全村都可以听到。 什么是BroadcastReceiver Android四大组件之一,BroadcastReceiver就相当于村里的大喇叭,用来在APP之间传数据的,是一种通信手段。系统自己在很多时候都会发送广播,比如电量低或

amynn的博客 420

Silvaco 学习笔记——物理模型:载流子产生复合模型

对载流子的复合机制进行总结

reactortiger的博客 1万+

android四大组件之广播接收者(一)

一、概念 BroadCastReceiver,广播接收者,android四大组件之一,它就像是生活中的收音机可以接收电台的广播一样,可以接收系统的广播或者用户自定义的广播。简单来说,广播接收者的作用有: 1.接收系统的广播,比如系统启动完成、电池低电量或者拨打电话等,我们可以通过一定的配置接收系统发送的这些广播从而知道这些事件的发生; 2.接收应用发送的广播,可以是本应用也可以是其他应用,从

2304

【Benchmark 性能测试全指南:从核心原理到 CINEBENCH 实战解析】

本文深度拆解基准测试(Benchmark)的底层逻辑,详解数据集、工作负载、度量指标三大核心要素,分步演示测试流程与统计分析要点。结合 CINEBENCH R23 实战案例,揭秘 CPU 性能评估方法论,助你掌握系统性能量化与优化的核心技能。

rong_ha_ha的博客 6329

从高德、百度地图下载POI数据?用这个工具5分钟搞定GCJ02/BD09到WGS84的坐标纠偏

本文详细解析了高德、百度地图POI数据坐标偏移问题,并提供了从GCJ02/BD09到WGS84的高效转换方案。通过开源工具如coordtransform和ArcGIS等专业软件,实现毫米级精度的坐标纠偏,适用于商业选址、GIS分析等场景,显著提升数据准确性和工作效率。

weixin_26789847的博客 450

Broadcast详解(有序广播,无序广播)最终广播,Bundle传递参数

17_Android中Broadcast详解(有序广播,无序广播)最终广播,Bundle传递参数,传递参数的时候指定权限,17_androidbundle 热度2 评论 262 www.BkJia.Com  网友分享于:  2015-07-13 09:07:17     浏览数12569次 17_Android中Broadcast详解(有序广播,无序广播)最终广播,Bundl

leixiongbo的博客 1479

「Unity3D」Addressable版本冲突解析:SBP与Addressables兼容性问题实战指南

本文深入解析Unity3D中Addressable与SBP(Scriptable Build Pipeline)版本冲突问题,提供实战解决方案。当遇到「Build Task CreateBuiltInShadersBundle failed」错误时,可通过版本匹配、临时资源引用或构建参数调整解决。文章详细分析兼容性原理,并给出版本组合指南与最佳实践,帮助开发者高效处理资源构建问题。

weixin_29001683的博客 410

有序广播修改添加bundle所带数据

突然想到有序广播测试时,自己忘了对其所带参数进行修改和添加测试了,在这里补上吧! 代码如下:package com.btzh.mybroatcasttest;import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.o

www121104115的博客 1359

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

WW、forever的博客 146

知识图谱开发实战:搭建上市公司知识图谱(二)

搭建上市公司知识图谱(二)学习目标1. 获取上市公司公开数据1.1 获取上市公司列表与行业信息1.2 代码展示2. 从网站爬取上市公司网页并存储为 HTML文件2.1 准备环境2.2 爬取上市公司公开信息3. 解析HTML文件,获取高管信息并存储为 csv 文件4. 设计知识图谱数据库4.1 实体4.2 关系4.3 属性4.4 特殊4.5 代码5. 知识图谱数据库查询实战5.1 实战:按照neo4j的数据格式,转换CSV文件5.2 实战:使用neo4j-admin 导入数据5.3 实战:使用neo4j-b

全网粉丝30W+,优快云、稀土掘金人工智能领域签约作者,人工智能、大模型、Python 爬虫,商务合作,请私信沟通。 2094

android组件广播的基础知识

上一篇博客大概记录了activity的基础知识,这篇博客记录下广播(Broadcast)的基础知识 广播 Broadcast是一种在应用程序间传递信息的机制,既可以在不同程序间传递信息,也可在同一程序内部传递信息。 广播接收器(Broadcast Receiver)是用来接收广播的。 android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样程序就可以只关注自己关心的内容。 广播的类型 广播主要分为四种类型:标准广播,有序广播,本地广播和粘性广播 (1)标准广播:是一种完全异步执行的广播,在广播发

Liu_A_Yu的博客 335

Moviepy自动化剪辑视频中的广告

本教程展示了如何使用 Python 中的 MoviePy 库,通过检测和剪辑广告段落来实现视频内容的清洁播放。通过广告检测算法和 MoviePy 剪辑功能的结合,可以自动化处理视频,极大提升编辑效率。在学习和应用中,理解广告检测的原理及其实现方法尤为重要,以便针对不同类型的视频进行调整。此外,MoviePy 的灵活性使其适用于多种视频编辑场景,适合自动化内容制作与优化。

Mr数据杨 3413

android四大组件(Activity,Service,BroadcastReceiver,Content Provider)

安卓的四大组建,五大布局Android四大组件:Activity、Service、Broadcast Receiver、Content Provider。1、 Activity 可以去本人博客activity了解学习是Android程序与用户交互的窗口,从视觉效果来看,一个Activity占据当前的窗口,响应所有窗口事件,具备有控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个

Mr_haimeng的博客 1358

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Android四大组件——BroadcastReceiver详解

一、 定义 BroadcastReceiver(广播接收器),属于Android四大组件之一 在Android开发中,BroadcastReceiver的应用场景非常多广播,是一个全局的监听器,属于Android四大组件之一 Android 广播分为两个角色:广播发送者、广播接收者 二、 作用 用于监听 / 接收 应用发出的广播消息,并做出响应 应用场景 a. 不同组件之间通信(包括应用内 / 不同应用之间) b. 与 Android 系统在特定情况下的通信 如当电话呼入时、网络可用时

QLHepburn的博客 1679

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Android 四大组件基础(Activity/Service/BroadcastReceiver/ContentProvider)工控场景用法

Android四大组件在工控场景中的应用与手机开发有显著差异。工控开发以Service为核心,负责后台数据采集(串口/Modbus)、设备监控等关键任务,需通过前台Service保证持续运行。Activity主要用于全屏数据显示和参数配置,需禁用旋转和返回键退出。BroadcastReceiver实现开机自启、外设状态监听等功能。ContentProvider则用于多应用间共享传感器数据。工控开发强调稳定性,四大组件需针对工业环境特殊配置,如固定屏幕方向、防进程回收等。

爱片闲串,爱钓鱼,爱中医,爱分享 534

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Android 四大组件——BroadcastReceiver(广播)

本文全面解析Android四大组件之一的BroadcastReceiver。主要内容包括:1)广播接收器定义及核心设计思想,作为响应系统或应用内事件的"事件监听器";2)工作原理,包括系统匹配和执行流程;3)两种广播类型(标准广播和有序广播)及使用示例;4)两种注册方式(静态和动态);5)本地广播的优势及使用方法;6)安全考量如权限设置和exported属性;7)最佳实践,包括避免耗时操作和生命周期管理;8)常用系统广播列表。文中通过有序广播的完整示例,演示了从权限检查到最终处理的链式流

indeedes的博客 1008

Android题集四大组件之Content provider、BroadcastReceiver

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人。

2401_85730911的博客 950

Android四大组件之一BroadcastReceiver总结

1、定义 BroadcastReceiver即广播,属于Android四大组件之一 广播分:广播发送者、广播接收者 2、作用 监听其它应用/系统应用发出的消息,自身做出响应。 3、应用场景 1、不同应用之间通信; 2、应用内通信; 3、获取系统一些状态变化; 4、实现原理 广播使用观察者模式,基于消息发布/订阅事件模型 5、广播注册方式 注册方式分:静态注册、动态注册 静态注册:在AndroidManifest.xml里通过****标签声明 此App...

ming15920的博客 238

Android四大组件之BroadcastReceiver

BroadcastReceiver全方位解析一、 定义 BroadcastReceiver (广播接收器),属于Android四大组件之一 在Android开发中,BroadcastReceiver的应用场景非常多 广播,是一个全局的监听器,属于 Android 四大组件之一,Android 广播分为两个角色:广播发送者、广播接收者二、 作用 用于监听 / 接收 应用发出的广播消息,并做出响应 应用

u014732103的博客 279

Android四大组件之一 BroadCastReceiver详解

一、什么是BroadCastReceiver? 即广播,是一个全局的广播监听器,属于Android四大组件之一。 理解广播和广播接收器 广播事件处理属于系统级的事件处理。 一个应用可以在发生特定事件时发送BroadCast,系统中任何应用只要注册了对应的Receiver就会接收到此BroadCast。 广播事件机制是应用程序(进程间)之间通信的一种手段。 二、BroadCastRece...

familyyan的博客 1077

【Android】四大组件之BroadcastReceiver

BroadcastReceiver用于监听系统或应用发出的广播事件,实现跨组件通信。

贫道绝缘子的博客 2070

Android 四大组件之 ContentProvider 与 BroadcastReceiver

四大组件里,Activity 是"看得见的脸"、Service 是"看不见的腿",剩下两个是搭起整个系统协作骨架的"管道"。

2301_76797664的博客 521

Android四大组件---BroadcastReceiver

前言: BroadcastReceiver(广播接收器),属于Android四大组件之一 在Android开发中,BroadcastReceiver的应用场景非常多 今天,我将详细讲解关于BroadcastReceiver的一切相关知识 目录: 下面小可会把自己使用广播的心得体会以及广播dev具体用途详细的讲解。 1:定义 广播,是一个全局的监听器,属于Android四...

hirezy 1928

安卓四大组件之——BroadcastReceiver广播的详细解析

BroadcastReceiver 身为安卓的四大组件之一,其使用率非常普遍,所以我们要熟练掌握其使用方法。 1,广播的注册方式有两种:静态注册和动态注册 1),静态注册:需要在Androidmanifest 中进行声明,主要用于全局APP中监听,只有完全退出APP才能让其停止工作。 2),动态注册:在代码中注册,不需要在Androidmanifest进行声明,其生命周期随着活

www121104115的博客 596

Android四大组件简述之BroadcastReceiver

BroadcastReceiver详细介绍:http://developer.android.com/reference/android/content/BroadcastReceiver.html

Ricky 2000
上一篇: Android 多线程编程初探
下一篇: Android 详解 build.gradle 文件
QDJdeveloper
博客等级 码龄11年 108粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值