美文网首页
BroadcastReceiver详解

BroadcastReceiver详解

作者: code希必地 | 来源:发表于2020-09-27 16:56 被阅读0次

1、广播的类型

广播分为标准广播和有序广播。

1.1、标准广播

标准广播是一种完全异步执行的广播,在广播发出之后,所有的BroadcastReceiver几乎在同一时刻收到这个广播消息,它们之间没有先后顺序,这种广播的效率较高,并且不能被拦截。

1.2、有序广播

有序广播是一种完全同步的广播,在广播发出后只能有一个BroadcastReceiver能接收到这个广播消息,当这个BroadcastReceiver中的逻辑执行完毕后,广播才能继续向下传递。所以这个广播是有顺序的,所以这种广播也是可以被拦截的,如果被拦截了后面的BroadCastReceiver则不能收到广播消息了。

2、系统广播的注册

广播的注册分为动态注册和静态注册。

2.1、动态注册系统广播

  • 1、创建BroadCastReceiver的子类,在onReceive()编写相应的逻辑。
class TimeChangeReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        context?.let {
            showToast(it, "收到了时间变化的广播")
        }
    }
}
  • 2、通过registerReceiver()注册广播监听
  • 3、在页面关闭时记得通过unregisterReceiver()注销广播监听,否则会因广播持有Activity引用导致内存泄露。
class ReceiverActivity : AppCompatActivity() {
    var receiver:TimeChangeReceiver?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_receiver)
        btn_regist.setOnClickListener {
            val intentFilter = IntentFilter()
            intentFilter.addAction(Intent.ACTION_TIME_TICK)
             receiver = TimeChangeReceiver()
            registerReceiver(receiver, intentFilter)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        receiver?.let {
            unregisterReceiver(it)
        }
    }
}

这样我们就注册系统时间变化的广播,在时间变化时广播了。

2.2、静态注册系统广播

动态注册广播可以很方便的注册和注销广播,但是这都是基于程序启动的状态下进行的,那么能不能在程序未启动时就能接收到广播呢?这就用到了静态注册广播,但是有很多恶意应用通过静态注册的方法监听系统的广播,然后频繁的唤醒应用导致用户手机的性能和电量,在Android8.0后,所有隐式广播都不能通过静态注册了,隐式广播是指没有指定那个应用程序接收广播。而大多数系统广播都是隐式广播,但是也有少数的特殊广播仍然能允许通过静态注册的方法注册,比如:开机广播,下面我们就通过静态注册的方法注册系统开机的广播。

  • 1、创建BootcastReceiver继承BroadCastReceiver
class BootReceiver:BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        context?.let {
           Toast.makeText(context,"开启",Toast.LENGTH_LONG).show()
        }
    }
}
  • 2、在Manifest中注册receiver
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application>
   <receiver android:name=".receiver.BootReceiver"
                  android:exported="true"
                  android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>

这样就完成了开机启动的静态广播的注册,不过为了保护用户的安全和隐私,需要对权限进行声明,在接收系统开启广播需要在Manifest中配置权限。
另外需要注意,在onReceive()不能执行耗时操作,onReceive()默认是在主线程中,进行耗时会阻塞主线程,如果非要执行耗时操作最好开启一个服务在服务中进行耗时操作,不建议开启线程来处理耗时操作,因为BroadCastReceiver的生命周期很短,可能在子线程结束前BroadCastReceiver已经退出,如果当BroadCastReceiver所在的进程结束,虽然该进程中可能有用户启动的新线程,但是由于该进程内没有活动的组件,系统会在内存紧张的时候,优先结束掉该进程,这就会导致BroadCastReceiver启动的子线程不能执行完。

3、自定义广播的动态注册和静态注册

自定义广播和系统广播的区别就在于,广播消息的发送是我们手动触发的,而系统广播是由系统触发的。下面我们简单看下使用过程。

3.1、动态注册自定义广播

代码如下:

class ReceiverActivity : AppCompatActivity() {
    var receiver:DynamicCustomReceiver?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_receiver)
        btn_regist.setOnClickListener {
            val intentFilter = IntentFilter()
            intentFilter.addAction(DynamicCustomReceiver::class.java.name)
             receiver = DynamicCustomReceiver()
            registerReceiver(receiver, intentFilter)
        }
        btn_send_broad.setOnClickListener {
            val intent=Intent(DynamicCustomReceiver::class.java.name)
            sendBroadcast(intent)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        receiver?.let {
            unregisterReceiver(it)
        }
    }
}

DynamicCustomReceiver

class DynamicCustomReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        context?.let {
            showToast(it, "自定义广播动态注册")
        }
    }
}

3.2、静态注册自定义广播

代码如下:
AndroidManifest中注册

<application>
<receiver android:name=".receiver.StaticCustomReceiver">
            <intent-filter>
                <action android:name="com.example.abu.listview.StaticCustomReceiver"/>
            </intent-filter>
        </receiver>
    </application>

创建广播

class StaticCustomReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        context?.let {
            showToast(it, "自定义广播静态注册")
        }
    }
}

发送广播

 val intent = Intent("com.example.abu.listview.StaticCustomReceiver")
            intent.setPackage(packageName)
            sendBroadcast(intent)

由于自8.0以后隐式广播不能进行静态注册了,所以这里通过setPackage()指定应用程序响应广播。

4、有序广播

前面我们学习标准广播的发送,下面看下有序广播是如何使用。

4.1、静态注册有序广播

AndroidManifest中注册有序广播

<receiver android:name=".receiver.StaticCustomReceiver">
            <intent-filter android:priority="100">
                <action android:name="com.example.abu.listview.StaticCustomReceiver"/>
            </intent-filter>
        </receiver>
        <receiver android:name=".receiver.StaticBroadcastReceiver">
            <intent-filter android:priority="90">
                <action android:name="com.example.abu.listview.StaticCustomReceiver"/>
            </intent-filter>
        </receiver>

可以看到我们给StaticCustomReceiverStaticBroadcastReceiver通过android:priority设置接收广播的优先级
创建StaticCustomReceiverStaticBroadcastReceiver

class StaticBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        context?.let {
            showToast(it, "另一个静态注册自定义广播")
        }
    }
}

class StaticCustomReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        context?.let {
            showToast(it, "自定义广播静态注册")
        }
        abortBroadcast()
    }
}

可以看到我们可以在abortBroadcast()来拦截优先级低的广播,使得优先级低的广播无法收到广播消息
发送广播

 val intent = Intent("com.example.abu.listview.StaticCustomReceiver")
            intent.setPackage(packageName)
            sendOrderedBroadcast(intent,null)

sendOrderedBroadcast(intent,null)发送了一个有序广播,第二个参数是权限相关的字符串传入null即可
上面是静态注册有序广播的过程,和动态注册有序广播的过程类似,区别就在于静态注册广播我们在AndroidManifest中指定优先级,动态注册我们在注册时通过intentFilter.priority=100来设定广播的优先级。

相关文章

  • Android四大组件BroadcastReceiver

    文章脑图 1、BroadcastReceiver史上最全面解析 2、BroadcastReceiver使用详解 3...

  • BroadcastReceiver详解!

    Android四大基本组件之一,这种组件本质上是一种全局的监听器,用于监听系统全局的广播消息。它可以接收来自系统和...

  • BroadcastReceiver详解

    1、广播的类型 广播分为标准广播和有序广播。 1.1、标准广播 标准广播是一种完全异步执行的广播,在广播发出之后,...

  • Android BroadcastReceiver详解

    简介 BroadcastReceiver(广播接收器)是Android四大组件之一,顾名思义,通过广播的方式进行消...

  • BroadcastReceiver 使用详解

    BroadcastReceiver作为Android四大组件之一,即广播。广播分为发送者和接收者。要想使用广播,首...

  • BroadcastReceiver 使用详解

    BroadcastReceiver作为Android四大组件之一,即广播。广播分为发送者和接收者。要想使用广播,首...

  • 三、BroadcastReceiver详解

    1.定义 是全局的监听器,属于四大组件之一,分为:广播发送者,广播接收者。 2.作用 用于监听/接收应用发出的广播...

  • Android BroadcastReceiver详解

    Broadcast Receiver是什么 Broadcast Receiver是四大组件之一,是一种广泛运用在应...

  • BroadcastReceiver-基础详解

    链接用于复习 https://www.jianshu.com/p/ca3d87a4cdf3

  • 组件之BroadcastReceiver详解

    一、BroadcastReceiver解析 (1)广播注册使用 (2)动态注册广播 (3)在配置文件中静态注册广播...

网友评论

      本文标题:BroadcastReceiver详解

      本文链接:https://www.haomeiwen.com/subject/saoxuktx.html