1. 子线程
- 4.0 之后联网需要在子线程中。 android.os.NetworkOnMainThreadException
- 联网需要添加权限。
- 子线程不能修改UI,修改UI必须在主线程进行,主线程又叫UI线程。
2. 消息机制
- 在主线程中创建一个Handler对象,并重写 handleMessage方法。
- 在子线程需要更新UI的地方,通过handler来发送消息。
- 发送的消息利用Message对象进行封装发送。
- UI线程在handleMessage中接受消息,更新UI。
3. Handler原理
- ActivityThread:程序的启动入口,为什么要介绍这个类,是因为该类就是我们说的主线程,它对Looper进行操作的。
- Handler:字面意思是操控者,该类有比较重要的地方,就是通过handler来发送消息(sendMessage)到MessageQueue和 操作控件的更新(handleMessage)。handler下面持有这MessageQueue和Looper的对象。
- MessageQueue:字面意思是消息队列,就是封装Message类。对Message进行插入和取出操作。消息池最多可以缓存50条空消息。
- Message:这个类是封装消息体并被发送到MessageQueue中的,给类是通过链表实现的,其好处方便MessageQueue的插入和取出操作。还有一些字段是(int what,Object obj,int arg1,int arg2)。what是用户定义的消息和代码,以便接收者(handler)知道这个是关于什么的。obj是用来传输任意对象的,arg1和arg2是用来传递一些简单的整数类型的。
- 详细介绍,可参考文章「一步一步分析Android的Handler机制 」
4. Handler 执行控制
主要有2种控制
- sendMessageAtTime 立即执行
- sendMessageDelayed 延迟执行
5. runOnUiThread
activity的一个api 这个方法可以让其中的runnable对象的run方法执行在ui线程
- 如果当前线程是主线程 立即执行run方法
- 如果当前线程不是主线程就会把runnable丢到消息队列 最终在主线程中执行
- 如果在子线程想跟新UI 业务逻辑比较简单就可以使用runOnUiThread方法
runOnUiThread(new Runnable() {
@Override
public void run() {
//这里的代码一定会执行在主线程中
Toast.makeText(MainActivity.this, "网络连接异常", Toast.LENGTH_SHORT).show();
}
});