Message是一种消息体,用于装载需要发送的对象,Android中子线程与主线程之间通信的时候,就需要通过消息来传递,你可以理解为子线程与主线程之间进行“聊天”时所发送的“聊天消息”。
什么是MessageQueue?
MessageQueue消息队列是用来存放所有消息的,遵循先进先出规则(FIFO),如果一个线程需要接收来自其它线程的消息,则必须为其创建一个消息队列,将接收到的消息丢进这个队列中,当需要时再取出来。
Looper就相当于管理者的角色,管理当前所属线程的MessageQueue,循环不断地管理MessageQueue接收和分发Message。
我们通过一段简单的代码片段来分析整个流程:
public class HandlerActivity extends Activity { //主线程的handler private Handler mainhandler; //子线程 private Thread myThread; //用来展示数据 private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); textView = (TextView)this.findViewById(R.id.hello); mainhandler = new Handler(){ public void handleMessage(android.os.Message msg) { switch(msg.what){ case 1: textView.setText(msg.what+"已经取到数据"); } }; }; myThread = new Thread(new Runnable(){ @Override public void run() { //在此处进行数据库或者网络连接等后台操作 Message msg = new Message(); msg.obj = "取到的数据:hello"; msg.what = 1; mainhandler.sendMessage(msg); } }); myThread.start(); } }
可以看到,首先在主线程中创建了一个mainhandler,用来处理和接收子线程发送过来的消息。再创建了一个子线程myThread,在子线程中进行了访问数据库的操作,访问完成后让message将数据携带上,在这里模拟数据为"取到的数据:hello",通过msg.obj将数据给message,msg.what是标志位,因为本例只有一个子线程,当有多个子线程的时候,handler需要辨识消息是属于哪个子线程发送的,就是通过what变量来分别。mainhandler.sendMessage(msg)是通过mainhandler将消息发送给主线程,在主线程中,通过handleMessage(android.os.Message msg)方法接收到消息,这里的参数正是子线程发送过来的消息,然后再通过switch分支处理消息,并进行UI更新-->textView.setText(msg.what+"已经取到数据")。
你会问,刚才的流程哪里有提到Looper以及MessageQueue?
其实,在刚才的流程中,只涉及了一个子线程,当有多个子线程时,主线程就需要与多个子线程进行交互,这个时候主线程接收到的消息就不止一两条,那么这些消息放在哪里呢?就放在MessageQueue中,而刚才说到handler是用来接收和处理消息的,其实handler并不是直接处理message,而是通过Looper来处理,Looper不断地从MessageQueue中循环取消息,一旦发现MessageQueue中有消息,就将其派发给handler去处理。
class LoginTask extends AsyncTask<String, Void, Integer>{ @Override protected Integer doInBackground(String... arg0) { // TODO Auto-generated method stub //可在此处进行各种后台操作 if(arg0.equals("")){ //如果传进来的参数为空,返回1 return 1; } else{ //如果传进来的参数不为空,返回2 return 2; } } @Override protected void onPostExecute(Integer result) { // TODO Auto-generated method stub super.onPostExecute(result); //这里接收的result即为上面doInBackground返回的结果 if(result==1){ //更新界面UI Intent intent = new Intent(MainActivity.this, HomePageActivity.class); startActivity(intent); } else{ //更新界面UI new AlertDialog.Builder(MainActivity.this).setMessage("账号或密码错误!").setPositiveButton("确定", null).show(); } } }
LoginTask loginTask = new LoginTask(); loginTask.execute("1"); //通过execute方法进行运行。
Handler handler = new Handler(){ Runnable runnable = new Runnable(){ public void run(){ //要做的事情,此处产生AsynTask实例,并execute handler.postDelayed(this,1000); //每1秒执行一次 } }; }