Android Handler消息处理

Android多线程

在了解Handler类之前,我们有必要熟悉以下Java的多线程编程

线程的基本用法

class MyThread extends Thread{
	public void run(){
	}
}
new MyThread().start();

更多的时候我们都会选择使用Runnable接口的方式来定义一个线程,如下

class MyThread implements Runnable{
	public void run(){
	}
}
MyThread myThread = new MyThread();
new Thread(myThread).start();



Handler类简介

Handler是Android提供的一个用来更新UI的机制(Android不允许在子线程更新UI),也是一个消息处理的机制。通过Handler类可以发送和处理Message对象到其所在线程的MessageQueue中。Handler类主要有以下两个作用、
1、在任意线程中发送消息
将Message应用sendMessage()方法发送到MessageQueue中,在发送时可以指定延时时间、发送时间以及携带的Bundle数据。当Looper循环到该Message时,调用相应的Handler对象handlerMessage()方法进行处理
2、在主线程中获取并处理消息
为了让主线程能在适当的时候处理Handler所发送的消息,必须通过回调方法来实现。

Handler类包含了一些用于发送和处理消息的常用方法
Android Handler消息处理_第1张图片
Android Handler消息处理_第2张图片




消息类(Message)

消息类是存放在MessageQueue中,一个MessageQueue中可以包含许多Message对象,每个Message对象可以通过Message.obtain()或Handler.obtainMessage()方法获得,属性如下:

  • arg1 用来存放整型数据
  • arg2 用来存放整型数据
  • obj 用来存放发送给接收器的Object类型的任意对象
  • replyTo 用来指定此Message发送到何处的可选Messager对象
  • what 用来指定用户自定义消息代码,能够用不同方式处理Message



循环者(Looper)

系统会为主线程创建Looper对象,开启消息循环,而子线程默认情况不会开启消息循环。
如果在子线程创建Handler对象,首先需要使用Looper类的 prepare() 方法初始化一个Looper对象,然后创建该Handler对象,最后使用Looper类的loop()方法启动Looper,从消息队列获取和处理消息.
Android Handler消息处理_第3张图片
Android Handler消息处理_第4张图片

从以上可以看出,Android的异步消息由4个部分组成:Message、Handler、MessageQueue和Looper。

  • Message是在线程之间传递的消息、可以在内部携带少量的消息,用于在不同线程之间交换数据。
  • Handler主要用于发送和处理消息。发送消息一般是使用Handler的sendMessage(),发出消息经过一系列处理,最终会传递到Handler的handleMessage()方法中。
  • MessageQueue消息队列,存放所有通过Handler发送的消息,每个线程只能由一个MessageQueue对象
  • Looper是管理MessageQueue的,调用Looper loop()方法后,进入一个无限循环,每当发现MessageQueue中存在一条消息,便会取出,传递到handleMessage()。每个线程中也只会有一个Looper对象

handler发送消息到MessageQueue中,然后Looper会尝试从MessageQueue取出消息,最后分发回Handler的handleMessage()方法中,由于Handler是在主线程中创建,所以此时handleMessage()方法代码会在主线程中运行,也就能安心进行UI操作。




实例:图片轮播

	slide_in_right.xml
    <translate
        android:duration="500"
        android:fromXDelta="100%p"
        android:toXDelta="0"/>

	slide_out_left.xml
	<translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="-100%p"/>
	
	activity_main.xml
	<ViewFlipper
       android:id="@+id/viewFlipper"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content">
   ViewFlipper>

MainActivity

public class MainActivity extends AppCompatActivity {
    final int FLAG_MSG = 0x001; //定义发送的消息代码
    private ViewFlipper flipper;
    private Message message;    //声明消息对象
    private int[] images = new int[]{	//图片
            R.drawable.img1,R.drawable.img2,
            R.drawable.img3,
            R.drawable.img4,
            R.drawable.img5,
            R.drawable.img6,
            R.drawable.img7,
            R.drawable.img8,
    };
    private Animation[] animation = new Animation[2];  //定义动画数组
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        flipper = (ViewFlipper) findViewById(R.id.viewFlipper);
        for(int i=0;i<images.length;i++){
            ImageView imageView = new ImageView(this);
            imageView.setImageResource(images[i]);
            flipper.addView(imageView);
        }
        //初始化动画数组
        animation[0] = AnimationUtils.loadAnimation(this,R.anim.slide_in_right);	//设置简单的淡入淡出动画
        animation[1] = AnimationUtils.loadAnimation(this,R.anim.slide_out_left);
        flipper.setInAnimation(animation[0]);
        flipper.setOutAnimation(animation[1]);
        message = Message.obtain();
        message.what = FLAG_MSG;
        handler.sendMessage(message);

    }
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what==FLAG_MSG){	//接收到的是消息标记,能用于处理不同类型的消息.
                flipper.showPrevious();
            }
            message = handler.obtainMessage(FLAG_MSG);	//获取要发送的消息.
            handler.sendMessageDelayed(message,3000);	//延迟3秒发送消息.
        }
    };
}	

运行效果如下,延迟3s切换图片
Android Handler消息处理_第5张图片




小结:

Thread和Handler的区别
创建一个Thread就是在程序中创建了一个子线程,用于在Android中不能在子线程(Worker线程)中更新主线程(UI线程)内的UI组件,因此Android引入消息传递机制,通过Looper、Handler和Message轻松实现在多线程中更新UI界面的功能。

你可能感兴趣的:(安卓)