终于到异步通讯了,小开心一下,但是总结和笔记总还是要有的!!!
先总结一下,异步通讯的几种方法
一、消息传递(sendMessage)
消息传递一共需要两个类
1、Handler
2、Message
3、Looper
4、MessageQueue
前两个类,是我们所需要的自己创建和设置的,而之后的两个,是系统机制,大家不用去创建或者配置,我在这里先解释一下这两个类的作用
每一个线程都会有这两个类,MessageQueue是一个Message的消息队列,而Looper的作用是操作这个队列(自动的哦),我们之后会在子线程内使用主线程传入的Handler对象的sendMessage方法将一个message插入主线程的MessageQueue队列,而主线程的Looper会时刻监听是否有新消息,当有消息后会回调主线程Handler的handlerMessage方法,这样就可以把两个线程串联起来
光说可能有点绕,一会看代码
Android提供这两个类,是我们能够很简单的实现消息的传输,还是看代码
注意:我为了看起来方便,把一些发送方法都写出来了,没有注释掉,只要用其中之一就可以了哦
一共有两个类,一个是主线程(UI)线程,和一个线程类
先看线程类
package com.ty.threaddemo1; import android.os.Handler; import android.os.Message; /** * Created by IT on 2017/3/8. */ //这是一个继承了Runnable接口的线程类 public class SendMessageRunnable implements Runnable { //线程里的Handler是通过其他线程通过线程类的构造函数传入的 private Handler handler; public SendMessageRunnable(Handler handler) { this.handler = handler; } //run函数里我们会像给我传入Handler的线程,发送数据 @Override public void run() { /** * 发送一个空消息 */ //发送一个内容为空,标记为1的message(标记我之后会说的),类似信号 handler.sendEmptyMessage(1); //在规定时间点发送消息 //第一个参数类似,第二个参数是一个绝对时间,我这里的1000只是一个不规范的举例,可以用当前时间,开机时间等作为标准 //添加或者减少时间 handler.sendEmptyMessageAtTime(1,1000); //延迟发送消息,第一个参数都是类似的标记,第二个参数是延迟的时间,单位是毫秒 handler.sendEmptyMessageDelayed(1,1000); /** * 发送一个不为空的消息 */ //既然消息不为空,那么就需要一个Message Message sendMsg = new Message(); //Message其实是一个集合了多数数据类型的类 //what就是上面代码里所说的标记,当收到Message时可以通过这个标记来筛选之后的操作 sendMsg.what = 1; //obj可以存放Message所携带的信息 sendMsg.obj = "SendMessage Test"; //Message里还有很多其他的成员变量可以使用,我这里就不演示了 //设置完就可以发送了,这里发送和上面的发送空消息几乎是一模一样的,我就不写具体的参数意义了 handler.sendMessage(sendMsg); handler.sendMessageAtTime(sendMsg,1000); handler.sendMessageDelayed(sendMsg,1000); //发送消息还有好几个函数,我就把比较常用列出来,其他的以后再说 } } 很简单吧,接下来再看UI线程
package com.ty.threaddemo1; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; public class MainActivity extends AppCompatActivity { @BindView(R.id.TV_Main) TextView TVMain; @BindView(R.id.PB_Main) ProgressBar PBMain; @BindView(R.id.BTN_Main) Button BTNMain; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); //初始化Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { //根据标记筛选 switch (msg.what) { case 1: TVMain.setText((String) msg.obj); break; } return true; } }); } @OnClick(R.id.BTN_Main) public void onClick() { SendMessageRunnable sendMessageRunnable = new SendMessageRunnable(handler); ExecutorService singleThread = Executors.newSingleThreadExecutor(); singleThread.execute(sendMessageRunnable); } }
在这个范例里,Message我是直接new出来的,其实这样做不利于资源的回收和复用,
建议使用obtain等方法,我会之后重新写一个单单关于Message的博客
今天我们先讲第一个方法,第二个post我再去研究一下