栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 广播机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 广播机制


广播机制简介

Android 提供了一套完整的 API,允许应用程序自由地发送和接收广播。发送广播需要借助之前学习的 Intent,而接收广播的方法则需要引入一个新的概念 —— BroadcasterReceiver

Android 中的广播主要分为两种类型:

  • 标准广播:一种异步执行的广播,广播发出后,所有的 BroadcasterReceiver 几乎会在同一时刻受到这条广播消息,没有任何时间顺序
  • 有序广播:一种同步执行的广播,广播发出后,同一时刻只有一个 BroadcasterReceiver 能够接受这条广播消息,当该 BroadcasterReceiver 中的逻辑执行完毕后,广播才会继续传递

接收系统广播

Android 内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种系统的状态信息

1. 动态注册监听时间变化

新建一个类,继承自 BroadcasterReceiver,并重写父类的 onReceive() 方法,这样当有广播来时,onReceive() 方法就会得到执行

class MainActivity : AppCompatActivity() {

    lateinit var timeChangeReceiver: TimeChangeReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val intentFilter = IntentFilter()
        intentFilter.addAction("android.intent.action.TIME_TICK")
        timeChangeReceiver = TimeChangeReceiver()
        registerReceiver(timeChangeReceiver, intentFilter)
    }

    inner class TimeChangeReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context?, intent: Intent?) {
            Toast.makeText(context, "Time has changed", Toast.LENGTH_SHORT).show()
        }
    }
}
  • 定义了一个内部类 TimeChangeReceiver,继承自 BroadcasterReceiver 并重写父类的方法,这样每当系统时间发生变化时,就会使用 Toast 提示一段文本信息
  • 在 onCreate() 方法创建一个 IntentFilter 实例,添加值为 android.intent.action.TIME_TICK 的 action,这也是系统时间发生变化时,系统会发出的广播的值
  • 创建 TimeChangeReceiver 实例,然后调用 registerReceiver() 方法进行注册,将 IntentFilter 实例和 TimeChangeReceiver 实例传进去,完成监听功能
2. 静态注册实现开机启动

动态注册的 BroadcasterReceiver 相对灵活,但必须在程序启动后才能接收广播,要想让程序在未启动的情况下也能接收广播,就需要使用静态注册的方式

创建类 BootCompleteReceiver,Exported 属性表示是否允许这个 BroadcasterReceiver 接收本程序以外的广播,Enabled 属性表示是否启用这个 BroadcasterReceiver,勾选这两个属性,点击 Finish 完成创建

class BootCompleteReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show()
    }
}

静态的 BroadcasterReceiver 要在 AndroidManifest.xml 文件中注册才可以使用。由于 Android 系统启动完成后会发出一条值为 android.intent.action.BOOT_COMPLETED 的广播,所以我们在 标签中添加一个 标签,并在里面声明相应的 action。另外,还必须在 AndroidManifest.xml 中进行权限声明。


    
    

    
        
        ...
        
        
            
                
            
        
    



发送自定义广播 1. 发送标准广播

新建一个 MyBroadcasterReceiver,并在 onReceive() 方法中加入如下代码:

class MyBroadcasterReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "received in MyBroadcasterReceiver", Toast.LENGTH_SHORT).show()
    }
}

然后在 AndroidManifest.xml 中对这个 BroadcasterReceiver 进行修改



	...
    
    
        
        ...
        
        
            
                
            
        
    


接下来修改 activity_main.xml,定义一个按钮,作为发送广播的触发点



    

修改 MainActivity 中的代码

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            val intent = Intent("com.example.broadcasttest.MyBroadcasterReceiver")
            intent.setPackage(packageName)
            sendBroadcast(intent)
        }
    }
}

这里对 setPackage() 方法做个说明,静态注册的 BroadcasterReceiver 是无法接收隐式广播的,而默认情况下我们发出的自定义广播都是隐式广播,因此这里要调用 setPackage() 方法,指定这条广播是发送给哪个应用程序的,从而让它变成一条显式广播

2. 发送有序广播

有序广播是一种同步执行的广播,并且可以被截断,我们再新建 AnotherBroadcasterReceiver

class AnotherBroadcasterReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "received in AnotherBroadcasterReceiver", Toast.LENGTH_SHORT).show()
    }
}

然后在 AndroidManifest.xml 中进行修改



   ...

    
        
		...

        
            
                
            
        
        
		...

    


到目前为止,程序发出的都是标准广播,要发送有序广播,就要重新回到 BroadcasterTest 项目,然后修改 MainActivity 中的代码

class MainActivity : AppCompatActivity() {
    
    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            val intent = Intent("com.example.broadcasttest.MyBroadcasterReceiver")
            intent.setPackage(packageName)
            sendOrderedBroadcast(intent, null)
        }
        ...
    }
}

sendOrderedBroadcast() 方法接收两个参数:第一个参数仍然是 Intent;第二个参数是一个与权限相关的字符串,这里传入 null 即可

接下来设定 BroadcasterReceiver 的先后顺序,修改 AndroidManifest.xml 中的代码



    ...

    
        
            
                
            
        
        
        ...
        
    


通过 android:priority 属性给 BroadcasterReceiver 设置优先级,优先级比较高的 BroadcasterReceiver 就可以先收到广播。既然 MyBroadcasterReceiver 获得了接收广播的优先级,那么 MyBroadcasterReceiver 就可以选择是否允许广播继续传递了

class MyBroadcasterReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "received in MyBroadcasterReceiver", Toast.LENGTH_SHORT).show()
        abortBroadcast()
    }
}

在 onReceive() 方法中调用 abortBroadcaster() 方法,就表示将这条广播截断,后面的 BroadcasterReceiver 将无法再接收这条广播


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/310138.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号