Android线程之间的通信架构(Handler消息机制)

  • 当主线程诞生时,就会去执行一个代码循环(Looper),以便持续监视它的信息队列(Message Queue简称MQ)。当UI事件发生了,通常会立即丢一个信息 (Message)到MQ,此时主线程就立即从MQ里面取出该信息,并且处理。
  • 例如,用户在UI画面上按下一个Button按 钮时,UI事件发生了,就会把onClick信息丢到 MQ里,于是,主线程会及时从MQ里取出onClick信息,然后调用Activity的onClick()函数去处理之。处理完毕之后,主线程又返回去继续执行信息循环,继续监视它的MQ,一直循环下去,直到主线程的生命周期的终了。 通常是进程被删除时,主线程才会被删除。
  • 即一个主线程有它自己专属的Looper对象,此线程诞生时,就会执行此对象里的信息循环。此外,一个主线程还会有其专属的MQ信息结构。如下图所示:
    在这里插入图片描述
  • 由于主线程会持续监视MQ的动态,所以在程序的任何函数,只要将信息(以Message 类别的对象表示)丢入主线程的MQ里, 就能与主线程沟通了。
  • 在Android里,也定义了一个Handler类别,在程序的任何函数里,可以诞生Handler对象来将Message对象丢入MQ里,与主线程进行沟通。
  • 在Android的预设情况下,主线程诞生时,就会拥有自己的Looper对象和MQ(即 Message Queue)数据结构。
  • 然而,主线程诞生子线程时,于预设情形 下,子线程并不具有自己的Looper对象和 MQ。由于没有Looper对象,就没有信息回圈(Message Loop),一旦工作完毕了,此子线程就结束了。
  • 既然没有Looper对象也没有MQ,也就不 能接受外来的Message对象了。则别的线 程就无法透过MQ来传递信息给它了。如果别的线程(如主线程)需要与子线程通讯时,就得要手动替它诞生一 个Looper对象和一个MQ。

Demo展示:

  1. 主线程丢信息给自己
package com.example.aaa;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{

	private Button btn1,btn2;
	private TextView textView;
	private Handler  h=new Handler(){
		 public void handleMessage(Message msg) {
			 if(msg.what==1)
   				 textView.setText((String)msg.obj);
		 };
	 };;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main2);
		
		 btn1=(Button) findViewById(R.id.btn1);
		 btn2=(Button) findViewById(R.id.btn2);
		 textView=(TextView) findViewById(R.id.textview);
		 btn1.setOnClickListener(this);
		 btn2.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn1:
			h.removeMessages(1);
			Message m=h.obtainMessage(1, "this is my message");
			h.sendMessage(m);
			break;
		case R.id.btn2:
			this.finish();
		default:
			break;
		}
	}
}

运行结果:
在这里插入图片描述

  1. 子线程丢信息给主线程
package com.example.aaa;


import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{

	private Button btn1,btn2;
	private TextView textView;
	private Timer timer=new Timer();
	private int k=0;
	private Handler  h=new Handler(){
		 public void handleMessage(Message msg) {
			 if(msg.what==1)
   				 textView.setText((String)msg.obj);
		 };
	 };;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main2);
		
		 btn1=(Button) findViewById(R.id.btn1);
		 btn2=(Button) findViewById(R.id.btn2);
		 textView=(TextView) findViewById(R.id.textview);
		 btn1.setOnClickListener(this);
		 btn2.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn1:
			TimerTask timerTask=new TimerTask() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					h.removeMessages(1);
					Message m=h.obtainMessage(1, Thread.currentThread().getName()+":"+String.valueOf(k++));
					h.sendMessage(m);
				}
			};
			timer.schedule(timerTask, 500, 1500);
			break;
		case R.id.btn2:
			this.finish();
		default:
			break;
		}
	}
}

运行结果:
在这里插入图片描述

  1. 替子线程诞生Looper和MQ
package com.example.aaa;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{

	private Button btn1,btn2,btn3;
	private TextView textView;
	private Thread t;
	private Handler h;
	private String str;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main2);
		
		 btn1=(Button) findViewById(R.id.btn1);
		 btn2=(Button) findViewById(R.id.btn2);
		 btn3=(Button) findViewById(R.id.btn3);
		 textView=(TextView) findViewById(R.id.textview);
		 btn1.setOnClickListener(this);
		 btn2.setOnClickListener(this);
		 btn3.setOnClickListener(this);
		 t=new Thread(new Task());
		 t.start();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn1:
			h.removeMessages(1);
			Message m=h.obtainMessage(1, Thread.currentThread().getName()+":"+String.valueOf(k++));
			h.sendMessage(m);

			break;
		case R.id.btn2:
			btn2.setText(str);
			break;
		case R.id.btn3:
			h.getLooper().quit();
			finish();
			break;
		}
	}
	class Task implements Runnable{
		@Override
		public void run() {
			// TODO Auto-generated method stub
			Looper.prepare();
			h=new Handler(){
				 public void handleMessage(Message msg) {
					 if(msg.what==1)
		   				 str=Thread.currentThread().getName()+",value="+String.valueOf(msg.what);
				 };
			 };
			 Looper.loop();
		}
	}
}

运行结果:
在这里插入图片描述

发布了61 篇原创文章 · 获赞 0 · 访问量 869

猜你喜欢

转载自blog.csdn.net/qq_36828822/article/details/103934472