广播

广播机制

简介

Android中的广播主要可以分为两种类型:标准广播和有序广播。

  • 标准广播:异步执行的广播。
  • 有序广播:同步执行的广播,并且可截断。

接收广播

监听广播需要事先注册。注册 BroadcastReceiver的方式一般有两种:在代码中注册和在AndroidManifest.xml中注册。其中前者也被称为动态注册,后者也被称为静态注册。

动态注册

  1. 创建意图过滤器IntentFilter;
  2. 添加监听广播;
  3. 使用接收器添加意图。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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)
}
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()
}
}
}

如果你想查看完整的系统广播列表,可以到如下的路径中去查看:<Android SDK> /platforms/<任意android api版本>/data/broadcast_actions.txt

静态注册

所有隐式广播都不允许使用静态注册的方式来接收。隐式广播指的是那些没有具体指定发送给哪个应用程序的广播,大多数系统广播属于隐式广播,但是少数特殊的系统广播目前仍然允许使用静态注册的方式来接收。这些特殊的系统广播列表详见https://developer.android.google.cn/guide/components/broadcast-exceptions.html。

静态的BroadcastReceiver一定要在AndroidManifest.xml文件中注册才可以使用。在<receiver>标签中进行配置,并进行权限声明。

BroadcastReceiver中是不允许开启线程的,当onReceive()方法运行了较长时间而没有结束时,程序就会出现错误。因此回调函数中不要添加过多的逻辑或者耗时操作。


发送广播

标准广播

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

  1. 创建意图对象(Intent对象),并把要发送的广播的值传入;
  2. 传入包名;
  3. 发送广播。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)
}
...
}
...
}

有序广播

发送有序广播只需要改动一行代码,即将sendBroadcast()方法改成sendOrderedBroadcast()方法。

在注册接收器的时候,通过android:priority属性给BroadcastReceiver设置了优先级,优先级高的先接收到广播。调用了abortBroadcast()方法,就表示将这条广播截断

应用

强制下线功能。

强制下线功能需要先关闭所有的Activity,然后回到登录界面。

实际操作不赘述。


Kotlin课堂

高阶函数

如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数就称为高阶函数。

函数类型:

1
(String, Int) -> Unit 

->左边的部分就是用来声明该函数接收什么参数的,多个参数之间使用逗号隔开,如果不接收任何参数,写一对空括号就可以了。而->右边的部分用于声明该函数的返回值是什么类型,如果没有返回值就使用Unit。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun plus(num1: Int, num2: Int): Int { 
return num1 + num2
}
fun minus(num1: Int, num2: Int): Int {
return num1 - num2
}
fun main() {
val num1 = 100
val num2 = 80
val result1 = num1AndNum2(num1, num2, ::plus)
val result2 = num1AndNum2(num1, num2, ::minus)
println("result1 is $result1")
println("result2 is $result2")
}

::plus和::minus这种写法,这是一种函数引用方式的写法,表示将plus()和minus()函数作为参数传递给num1AndNum2()函数。

内联函数

内联函数的用法非常简单,只需要在定义高阶函数时加上inline关键字的声明即可。

内联的函数类型参数在编译的时候会被进行代码替换,因此它没有真正的参数属性。非内联的函数类型参数可以自由地传递给其他任何函数,因为它就是一个真实的参数。

内联函数所引用的Lambda表达式中是可以使用return关键字来进行函数返回的,而非内联函数只能进行局部返回。非内联函数Lambda表达式中是不允许直接使用return关键字的,这里使用了return@printString的写法,表示进行局部返回。

声明了crossinline之后,我们就无法在调用runRunnable函数时的Lambda表达式中使用return关键字进行函数返回了,但是仍然可以使用return@runRunnable的写法进行局部返回。将高阶函数声明成内联函数是一种良好的编程习惯。


Git

常用命令如下:

1
2
3
4
git init # 创建代码仓库
git add [文件路径] # 添加代码
git add . # 添加所有改动
git commit -m "备注" # 提交代码