Android多线程编程


文章目录

  • Android多线程编程
  • 线程的基本用法
  • 在子进程中更新UI
  • 解析异步消息处理机制


线程的基本用法

定义一个线程只需要新建一个类继承自Thread,然后重写父类的run()方法即可

class MyThread : Thread(){
	override fun run(){
	  //编写具体逻辑
	}
}

启动线程很简单

MyThread().start()

当然我们也可以选择用Runnable接口

class MyThread : Runnable{
	override fun run(){
	//编写逻辑
	}
}

启动线程稍微有点不一样

val myThread = MyThread()
Thread(myThread).start()

可以看到,首先Thread需要接收一个Runnable参数,接着在调用start()
第三种写法是使用lambda方式

Thread{
	//编写具体逻辑
}.start()

这是再java中的写法,再kotlin中会更加简单

thread{
//编写具体逻辑
}

这是Kotlin内置的一个顶层函数,只需要再{}中写具体逻辑就可以,甚至都不需要写start()

在子进程中更新UI

假如我们要实现以下功能:点击按钮后文本内容改变
我们使用子进程的方式实现。

class MainActivity : AppCompatActivity() {  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main)  
        val binding = ActivityMainBinding.inflate(layoutInflater)  
        setContentView(binding.root)  
        binding.changeTextBtn.setOnClickListener {  
            thread {  
                binding.textView.text = "Nice to meet you "  
            }  
        }    }  
}

Android多线程 如何处理异步任务的 阻塞回调_android

这是因为Android是不允许在子进程中进行UI操作的。
修改代码为

class MainActivity : AppCompatActivity() {  
    val updateNext = 1  
    val handler = object : Handler(Looper.getMainLooper()){  
        override fun handleMessage(msg: Message) {  
            val textView = findViewById<TextView>(R.id.textView)  
            when(msg.what){  
                updateNext ->textView.text = "Nice to meet you"  
            }  
        }  
    }  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main)  
        val binding = ActivityMainBinding.inflate(layoutInflater)  
        setContentView(binding.root)  
        binding.changeTextBtn.setOnClickListener {  
            thread {  
               val msg = Message()  
                msg.what = updateNext  
                handler.sendMessage(msg)  
            }  
        }    }  
}

首先新建updateText变量,用于表示更新TextView的这个动作。
然后新增一个handler对象,且重写父类handleMessage方法,后根据msg的what内容判断,当接收到updateText时,更新UI。
再来看看changeTextBtn点击事件内容,首先是创建了一个Message对象,后将msg,what设置为updataText,然后调用sendMessage方法发送出去。
这个就是异步消息处理,以下是它的内容讲解

解析异步消息处理机制

异步消息处理主要由四个部分组成

  1. Message :在线程之间传递少量信息
  2. Handler : 用于发送和处理
  3. MessageQueue : 消息队列,用于存放Handler发送的信息
  4. Looper : 管家,调用Looperloop方法后,会进入一个无限循环中,每当发现信息队列中有信息,就会将他取出,并且传递到Handler的handleMessage中。
    了解一下主要流程
    首先在主线程中创建一个Handler对象,并且重写handleMessage()方法,然后当子线程需要改变UI时,新建一个Message对象,通过handle发送出去。这样这条信息就被添加到MessageQueue中等待被处理。而且Looper会一直尝试从MessageQueue中取出信息,最后分发到HandlerhandlerMessage中。(Handle的构造对象中传入了Looper.getMainLooper)