Android中的异步消息处理主要由4个部分组成:Message、Handler、MessageQueue和Looper。
首先需要在主线程当中创建一个Handler对象,并重写handleMessage()方法,在子线程中通过创建message对象通过sendMessage发送出去,这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handler的handleMessage()方法中。
class MainActivity : AppCompatActivity() {private val updateText = 1private lateinit var text: TextViewprivate lateinit var button: Buttonprivate val handler = object : Handler(Looper.getMainLooper()) {override fun handleMessage(msg: Message) {super.handleMessage(msg)//接受处理消息when (msg.what) {updateText -> text.text = "${System.currentTimeMillis()}"}}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)text = findViewById(R.id.textView)button = findViewById(R.id.button)button.setOnClickListener {thread {val msg = Message()msg.what = updateTexthandler.sendMessage(msg)//发送消息}}}
}
AsyncTask背后的实现原理也是基于异步消息处理机制的,只是Android帮我们做了很好的封装而已
AsyncTask是一个抽象类,必须创建一个子类去继承它。在继承时可以为AsyncTask类指定3个泛型参数。
**Params:**在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。
**Progress:**在后台任务执行时,如果需要在界面上显示当前的进度。
**Result:**当任务执行完毕后,如果需要对结果进行返回。
需要经常重写的几个方法(自动调用):
class DownloadTask : AsyncTask() {override fun onPreExecute() {//初始化ui界面}override fun doInBackground(vararg params: Unit?) = try {while (true) {val downloadPercent = doDownload() // 这是一个虚构的方法publishProgress(downloadPercent)//更新uiif (downloadPercent >= 100) {break}}true} catch (e: Exception) {false}override fun onProgressUpdate(vararg values: Int?) {//更新ui界面}override fun onPostExecute(result: Boolean) {progressDialog.dismiss()// 关闭进度对话框// 在这里提示下载结果if (result) {Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show()} else {Toast.makeText(context, " Download failed", Toast.LENGTH_SHORT).show()}}
}
简单来说,使用AsyncTask的诀窍就是,在doInBackground()方法中执行具体的耗时任务,在onProgressUpdate()方法中进行UI操作,在onPostExecute()方法中执行一些任务的收尾工作。如果想要启动这个任务,只需编写以下代码即可:DownloadTask().execute()
也可以给execute()方法传入任意数量的参数,这些参数将会传递到DownloadTask的doInBackground()方法当中。