Hanler、Loop、MessageQueue的工作原理

1.Handler类介绍:

  A.在新启动的线程中发送消息。

  B.在主线程中获取、处理消息。

Handler类包含的方法:

  void handleMessage(Message msg):处理消息的方法。该方法通常用于被重写。

  final boolean hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息

  final boolean hasMessages(int what,Object object):检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息。

  多个重载的Message obtainMessage():获取消息。

  sendEmptyMessage(int what):发送空消息

  final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定多少毫秒之后发送空消息。

  final boolean sendMessage(Message msg ):立即发送消息。

  final boolean sendMessageDelayed(Message msg,long delayMillis):指定多少毫秒之后发送消息。

2.Handler、Loop、MessageQueue的工作原理:

  Message:Handler接收和处理的消息对象

  Looper:每个线程只能拥有一个Looper。它的loop方法负者读取MessageQueue中的消息,读到信息之后就把消息交给发送该消息的Handler进行处理。

  MessageQueue:消息队列,它采用先进先出的方式来管理Message。程序创建Looper对象时会在它的构造器中创建Looper对象。

  Handler:它的作用有两个-发送消息和处理消息,程序使用Handler发送消息,被Handler发送的消息必须被送到指定的MessageQueue。也就是说,如果希望Handler正常工作,必须在当前线程中有一个MessageQueue,否则消息就没有MessageQueue进行保存了。不过MessageQueue是在由Looper负载管理的,也就是说,如果希望Handler正常工作必须在当前线程中有一个Looper对象。为了保存当前线程中有Looper对象,可以分两种情况处理。(A、B)

  A.主UI线程中,系统已经初始化了一个Looper对象,因此程序直接创建Handler即可,然后就可通过Handler来发送消息、处理消息。

  B.程序员自己启动的子线程,程序员必须自己创建一个Looper对象,并启动它。创建Looper对象调用它的perpare()方法即可。

3.总结:

  Looper:每一个线程只有一个Looper,它负责管理MessageQueue,会不断地从MessageQueue中取出消息,并将消息分给对应的Handler处理。

  MessageQueue:由Looper负责管理。它采用先进先出来管理Message。

  Handler:它能把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息。

4.示例

  自动播放图片示例:

  Handler在主UI线程中时(在drawable中添加一些图片)

  

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
    android:id="@+id/imgView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</LinearLayout>
布局代码
public class HandlerActivity extends Activity {

    //定义图片数组
    int [] images = new int[]{
            R.drawable.a1,
            R.drawable.a2,
            R.drawable.a3,
            R.drawable.a4,
            R.drawable.a5,
            R.drawable.a6
    };
    int currentImageIndex=0;//当前显示的图片
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);

        final ImageView imgView = (ImageView)findViewById(R.id.imgView);
        final Handler handler = new Handler(){

            //处理消息的方法,一般用于被重写
            @Override
            public void handleMessage(Message msg) {
                if(msg.what == 0x1233){
                    imgView.setImageResource(images[currentImageIndex++ % images.length]);//设置显示的图片
                }
            }
        };


        //创建一个定时器
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                handler.sendEmptyMessage(0x1233);
            }
        },0,1200);

    }
}
自动播放图片

  求输入数范围内的所以质数示例:  

  Handler在程序员自己创建的线程中时

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_height="wrap_content">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="数字:"/>
    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editNumber"/>
</LinearLayout>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnGetCalPrime"
        android:text="获取质数"/>
</LinearLayout>
布局代码
public class CalPrimeActivity extends Activity {
    EditText editNumber = null;
    String upper_num = "upper";
    CalThead calThead;

    class CalThead extends  Thread{
        public Handler handler=null;
        @Override
        public void run() {
            Looper.prepare();
            handler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    if (msg.what == 0x123){
                        int upper = msg.getData().getInt(upper_num);
                        List<Integer> nums = new ArrayList<Integer>();
                        outer:
                        for (int i=2;i<=upper;i++){
                            for (int j=2;j<=Math.sqrt(i);j++){
                                if (i != 2 && i%j == 0){
                                    continue  outer;
                                }
                            }
                            nums.add(i);
                        }
                        Toast.makeText(CalPrimeActivity.this,nums.toString(),Toast.LENGTH_LONG).show();
                    }
                }
            };
            Looper.loop();
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calprime);
        editNumber = (EditText)findViewById(R.id.editNumber);
        calThead = new CalThead();
        calThead.start();

        Button btn = (Button)findViewById(R.id.btnGetCalPrime);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cal();
            }
        });

    }

    public void  cal (){
        Message msg = new Message();
        msg.what=0x123;
        Bundle bundle = new Bundle();
        bundle.putInt(upper_num,Integer.parseInt(editNumber.getText().toString()));
        msg.setData(bundle);
        calThead.handler.sendMessage(msg);
    }

}
后台代码

效果图片:

 

posted @ 2015-08-23 14:17  聆听的风声  阅读(604)  评论(0编辑  收藏  举报