当执行一些耗时的操作,比如发起网络请求,可以考虑创建子线程来执行相关代码。而且,Android的UI是线程不安全的,所以想要更新应用程序的UI元素,必须在主线程中进行,否则会出现异常(程序运行崩溃)。但这样问题也就来了,比如说我在某个项目需要通过一系列复杂的逻辑来判断是否在此时更新UI,因为逻辑比较复杂,所以最好是在子线程中处理,但是又因为更新UI(Android的UI线程不安全)不能在子线程中进行,那么这时候遇到了两难的情况,需要找出一个方法来保证既可以在子线程中处理复杂逻辑,又能成功通过某种方法更新UI。
当考虑到以上因素,所以需要熟悉多线程编程的相关知识。
线程使用方式一:
新建一个类MyThread继承自Thread类。
class MyThread extends Thread{
@override
public void run(){
// 处理具体逻辑
}
}
最后启动方式为new MyThread().start();这种方法有个缺点,使用继承导致耦合性较高。
线程使用方式二:
使用一个类去实现Runnable的接口。
class MyThread implements Runnable{
@override
public void run(){
// 处理具体逻辑
}
}
最后启动方式为new Thread(new MyThread()).start();
线程使用方式三:(本人比较喜欢的方法)
使用匿名类直接new Runnable()。
new Thread(new Runnable(){
@override
public void run(){
// 处理具体逻辑
}
}
}).start();
关于异步消息处理机制:一种可以允许在子线程中进行UI操作的方法。(线程间通信)
具体的代码实现如上,使用上述异步消息处理机制需要创建Handler的新对象并且主动重写handlerMessage方法(定义该对象的同时使用匿名类的方式来重写handleMessage方法),另一处是创建一个Message消息的对象,并且给该参数的what参数赋值(int),且该参数用于使handlerMessage成功匹配到需要执行的操作。当然,当Message的新对象message.what赋值成功后,还需要接着通过先前new出来的handler对象来传递,即handler.sendMessage(message)。
Android的异步消息处理机制主要由4个部分组成:Message,Handler,MessageQueue,Looper。
1.Message是可在线程之间传递的消息,在内部携带少量的信息,用于在不同线程之间交换数据,除了what字段,还可以使用arg1和arg2字段,例如这样的写法,就可以保证传输进三个Integer型数据。
2.Handler也就是处理者的意思,主要用于发送和处理消息,通过handler可以更新UI,也可以在线程间传递少量信息。他主要是用于发送和处理消息。发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列地辗转处理后,最终会传递到Handler的handlerMessage()方法中。
3.MessageQueue是消息队列的意思,所有通过Handler发送的message实例都存在这里,每个线程只有一个MessageQueue对象。(关于已经被Looper取出过的消息是否就是MessageQueue中再也么有该消息实例了需要等以后在探究。)
4.Looper苦逼的管家,郭霖大佬说Looper相当于每个线程中的唯一的MessageQueue的唯一管家,在每个线程中,MessageQueue只有一个,相对应的Looper也只有一个。调用了Looper的loop()方法后,就会进入到一个无限循环
emmm。runOnUiThread()就是这种异步消息处理机制的一种接口封装。然后后续还有一个AsyncTask的介绍,这和runOnUIThread相同,背后的实现原理都是基于异步消息处理机制。啊啊啊,封装真是个好东西!