读后感作业

Android中Service机制

基础

广播的类型:标准广播(高效,无法截断)、有序广播(同步执行,可以截断,有先后顺序)

接收系统广播

动态注册监听系统广播

BroadcastReceiver的创建方法:新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()方法。

书上的示例,监听系统时间变化的广播,显示通知。

class MainActivity : AppCompatActivity() {
lateinit var timeChangeReceiver: TimeChangeReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//过滤要监听的广播:系统时间发生变化发出的“android.intent.action.TIME_TICK”
val intentFilter = IntentFilter()
intentFilter.addAction("android.intent.action.TIME_TICK")
//创建TimeChangeReceiver的实例,并调用registerReceiver注册
timeChangeReceiver = TimeChangeReceiver()
registerReceiver(timeChangeReceiver, intentFilter)
}
override fun onDestroy() {
super.onDestroy()
//销毁时取消注册
unregisterReceiver(timeChangeReceiver)
}
inner class TimeChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Toast.makeText(context, "Time has changed", Toast.LENGTH_SHORT).show()
}
}
}
//targetApi 31测试是可以这样写的

静态注册实现开机启动

喜闻乐见的被滥用的功能,频繁啊唤醒的恶意App,即使可能离不来,笑。

AndroidStudio创建静态BroadcastReceiver,以及会自动在AndroidManifest中注册。

<receiver>标签中添加<intent-filter>声明对应action,并且声明接收开机广播的权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest
...>
<!--接收开机广播毕竟是个有点敏感的权限呢-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<application
...>
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!--声明对应action-->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
...
</application>
</manifest>

实体机和虚拟机盯着看了半天没看到Toast消息,不知道为什么,不过加了条log的输出,也算是看到了,真的开机自启动了呢!

自定义广播

发送标准广播

class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val intent = Intent("com.example.broadcasttest.MY_BROADCAST")
//指定这条广播是发送给哪个应用程序的,让它变成一条显式广播
intent.setPackage(packageName)
sendBroadcast(intent)
}
...
}
...
}

接收广播的BroadcastReceiver,和前面的写法是一样的

广播是使用Intent来发送的,因此你还可以在Intent中携带一些数据传递给相应的BroadcastReceiver

发送有序广播

有序广播的发送

sendBroadcast(intent)改变为sendOrderedBroadcast(intent, null),第二个参数是一个与权限相关的字符串。

有序广播的接收

...
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<!--这里的priority为BroadcastReceiver设置了优先级,优先级高的先收到广播-->
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
...

有序广播的截断

class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Toast.makeText(context, "received in MyBroadcastReceiver",
Toast.LENGTH_SHORT).show()
abortBroadcast()//截断这条广播
}
}

广播的最佳实践

要在onReceive()方法中弹出一个对话框,需要动态注册的BroadcastReceiver,可以在BaseActivity中注册,所有Activity都继承自BaseActivity。

将注册和取消注册放在onResume()onPause()的生存周期,就能做到只保证栈顶的Activity才能接收这条广播。

open class BaseActivity : AppCompatActivity() {
...
override fun onResume() {
super.onResume()
val intentFilter = IntentFilter()
intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE")
receiver = ForceOfflineReceiver()
//注册Receiver
registerReceiver(receiver, intentFilter)
}
override fun onPause() {
super.onPause()
//取消注册
unregisterReceiver(receiver)
}
...
}
posted @   satou_matsuzaka  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
历史上的今天:
2023-05-10 编程打卡:C++语言程序设计

This is a Test

メイドノココロハ アヤツリドール
点击右上角即可分享
微信分享提示