安卓学习之六–广播机制
广播机制简介
Android应用程序都可以对自己感兴趣的广播进行注册,,这样程序就可以接受自己所关心的广播内容,这些内容可能来自系统,也可能来自应用程序,在Android中提供一套完整的API,允许程序接受和发送广播,接受广播需要用到–BroadcasReceiver
首先广播方式分为标准广播和有序广播
标准广播:完全异步执行的广播,在发送广播后,所有BroadcasReceiver会几乎同时接受广播消息,所有效率高,但是不可以截断。
有序广播:感觉就像排队一样,同一时刻只有一个BroadcasReceiver接受广播消息,但这个BroadcasReceiver逻辑执行完毕后,后一个BroadcasReceiver在接受,依次传递出去,优先级别高的BroadcasReceiver先接受,依次内推,有序广播是可以被截断的,一当截断后面的就无法接受消息。
动态注册监听时间变化
动态注册是在代码中注册,首先我们兴建一个BroadcastTest项目,在ManActivity中定义一个内部类去继承BroadcasReceiver,并且重写父类onReceive方法,这样随着时间变化这个方法就会得到执行
package com.example.broadcastreceiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
class MainActivity : AppCompatActivity() {
lateinit var timeChangerReceiver:TimeChangeRecevier
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//获取IntentFilter实例
val intentFilter=IntentFilter()
//但时间发生变化,系统会发出一条值为"android.intent.action.TIME_TICK"广播
//也就是我么的BroadcastReceiver想要监听什么广播
intentFilter.addAction("android.intent.action.TIME_TICK")
timeChangerReceiver=TimeChangeRecevier()
//这个方法是进行注册,这样才可以接受值为android.intent.action.TIME_TICK广播
registerReceiver(timeChangerReceiver,intentFilter)
}
override fun onDestroy() {
super.onDestroy()
//这里动态注销注册
unregisterReceiver(timeChangerReceiver)
}
inner class TimeChangeRecevier:BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
Toast.makeText(context,"This has changed",Toast.LENGTH_SHORT).show()
}
}
}
复制代码
随着时间变化而发出广播效果如下
静态注册实现开机启动
动态注册虽然灵活,但是要在要在程序启动后才能接受,反之就是使用静态注册
静态注册实现开机启动
动态注册虽然灵活,但是要在要在程序启动后才能接受,反之就是使用静态注册.
理论上动态注册能够监听到广播,那么静态也应该可以,在以前确实可以,但是因为有大量恶意程序利用这个机制在为启动程序时监听广播系统,导致手机频繁被后台唤醒,严重影响了手机的性能和电量,所以每次安卓版本更新,几乎都会削弱静态注册功能,在Android8.0之后所以的隐士广播都不允许使用静态注册了。
隐士广播:是指没有具体指定发送给那个应用程序的广播
当然一些特殊的广播是允许的:例如开机广播
android.intent.action.BOOT_COMPLETED
复制代码
动态注册我们是通过内部类,现在我们就通过Android Studio快捷方式创建,
右击com.example.broadcastreceiver->new->other->Broadcast Receiver
这里我把类名改为BootCompleteReceiver
Exprodted:表示允许这个BroadcasReceive接受本程序以外的广播
Enabled:表示是否启用这个BroadcasReceive
下面修改BootCompleteReceiver类的代码,在onReceived方法中使用Toast弹出提示消息
package com.example.broadcastreceiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast
class BootCompleteReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
Toast.makeText(context,"Boot Complete",Toast.LENGTH_SHORT).show()
}
}
复制代码
静态注册的BroadcasReceiv一定要在ActivityManifest.xml中注册,由于我们是通过快捷方式注册,所以直接注册好了,实例如下:
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true"></receiver>
复制代码
要想收到开机广播,还得修改ActivityManifest.xml代码
因为权限问题要加上
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
复制代码
最后添加<receiver标签下添加action
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
复制代码
发送标准广播
首先定义一个BroadcastReceiver接受广播
package com.example.broadcastreceiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast
class MyBoardcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
Toast.makeText(context,"recevied in MYboardcastReciver",Toast.LENGTH_SHORT).show()
}
}
复制代码
然后在ActivityManifest对BroadcastReceiver进行修改,这里让BoardcastReceiver接受com.example.broadcasttest.MY_BRPADCAST广播
<receiver
android:name=".MyBoardcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BRPADCAST"/>
</intent-filter>
</receiver>
复制代码
我们要发送这样一条广播,接下来修改Man.xml代码,增加一个按钮布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send Broadcast"/>
</LinearLayout>
复制代码
然后在ManActivity中设置监听器
首先构建一个Intent对象,把发送广播传入
调用 intent.setPackage(packageName)传入当前应用程序的包名
sendBroadcast(intent)指定这条广播发送给具体应用程序
class MainActivity : AppCompatActivity() {
lateinit var timeChangerReceiver:TimeChangeRecevier
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button:Button=findViewById(R.id.button)
button.setOnClickListener{
val intent=Intent("comcom.example.broadcasttest.MY_BRPADCAST")
intent.setPackage(packageName)
sendBroadcast(intent)
}
.....
复制代码