读后感作业
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) } ... }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
2023-05-10 编程打卡:C++语言程序设计