1. 子线程

  1. 4.0 之后联网需要在子线程中。 android.os.NetworkOnMainThreadException
  2. 联网需要添加权限。
  3. 子线程不能修改UI,修改UI必须在主线程进行,主线程又叫UI线程。

2. 消息机制

  1. 在主线程中创建一个Handler对象,并重写 handleMessage方法。
  2. 在子线程需要更新UI的地方,通过handler来发送消息。
  3. 发送的消息利用Message对象进行封装发送。
  4. UI线程在handleMessage中接受消息,更新UI。

3. Handler原理

image.png

  • 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是用来传递一些简单的整数类型的。
  1. sendMessageAtTime 立即执行
  2. sendMessageDelayed 延迟执行

5. runOnUiThread

activity的一个api 这个方法可以让其中的runnable对象的run方法执行在ui线程

  • 如果当前线程是主线程 立即执行run方法
  • 如果当前线程不是主线程就会把runnable丢到消息队列 最终在主线程中执行
  • 如果在子线程想跟新UI 业务逻辑比较简单就可以使用runOnUiThread方法
  1. runOnUiThread(new Runnable() {
  2. @Override
  3. public void run() {
  4. //这里的代码一定会执行在主线程中
  5. Toast.makeText(MainActivity.this, "网络连接异常", Toast.LENGTH_SHORT).show();
  6. }
  7. });