hanlder 机制原理和使用

1,hanlder  介绍

    【1】介绍:

        消息机制: handler是更新UI界面的机制,也是消息处理的机制,我们可以发送消息,也可以处理消息

   【2】handler的出现:

        问题:ANR :application not response  应用无响应

            hanlder 机制原理和使用

             当应用程序在主线程(main线程 ui线程)进行耗时(比如连接网络,拷贝大的数据 )的操作 一般5秒钟无响应就会报ANR为了避免出现ANR我们把耗时操作放在子线程去做,但是在子线程去更新UI会报错误

10-06 02:17:57.778: W/System.err(1596): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

只有在主线程才能更新UI,我们要开始用Handler了。

【3】hanlder 简单使用:

A,开启子线程处理耗时操作,使用handler传输数据:

// 实现按钮点击事件

    public void click(View v) {

        

        //创建一个子线程

        new Thread() {

            public void run() {

                try {

                    if(xxxx){

                        // 把耗时的操作放到子线程里面 bitmap 是要传输的数据

                        Bitmap bitmap = BitmapFactory.decodeStream(in);

                        // 获取message对象,不去 new Message() 使用obtain方法是为了避免创建过多的对象

                        Message msg = Message.obtain();

                        // 数据塞进msg里面

                        msg.obj = bitmap;

                        // 给msg 加一个标识在handler 可以分类进行逻辑处理

                        msg.what = REQUESTSUCESS;

                        handler.sendMessage(msg);

                    }else {

                        Message msg = Message.obtain();

                        msg.what = REQUESTFAIL;

                        handler.sendMessage(msg);

                    }

                } catch (Exception e) {

                    e.printStackTrace();

                    Message msg = Message.obtain();

                    msg.what = REQUESTEXCEPTION;

                    handler.sendMessage(msg);

                }

            }

        }.start();

        

        

 

B,创建handler成员变量,接收数据进行UI操作:

    protected static final int REQUESTSUCESS = 0;  

    protected static final int REQUESTFAIL = 1;

    protected static final int REQUESTEXCEPTION= 2;

    //定义一个handler

    private Handler handler = new Handler(){

        //在这个方法里面处理消息

        public void handleMessage(android.os.Message msg) {

            

            switch (msg.what) {

            case REQUESTSUCESS:

                //[1]获取我们携带的数据

                Bitmap bitmap = (Bitmap) msg.obj;

                //[2]把btimap展示到imagview上

                iv.setImageBitmap(bitmap);

                break;



            case REQUESTFAIL:

                iv.setImageBitmap(null);

                Toast.makeText(getApplicationContext(), "图片不存在", 1).show();

                break;

            case REQUESTEXCEPTION:

                iv.setImageBitmap(null);

                Toast.makeText(getApplicationContext(), "图服务器忙", 1).show();

                break;

            }

        };

    };

 

2,hanlder 原理:

    【1】相关方法和类

          looper类: 消息封装的载体。内部包含一个MessageQueue,所有的Handler发送的消息都走向这个消息队列

        Looper.Loop方法,就是一个死循环,不断地从MessageQueue取消息,如果有消息就处理消息,没有消息就阻塞。

          MessageQueue, 存储消息的容器是一个消息队列,添加消息,处理消息

 

A,looper.loop方法:

hanlder 机制原理和使用

   B,Message 类中的变量 msg.target 实际调用的是Handler

hanlder 机制原理和使用

C,Handle处理系统消息

hanlder 机制原理和使用

 

流程:  handler.sendMessage(msg); 发送一个消息,消息进入MessageQueue 消息队列里,looper.loop无限循坏去监听MessageQueue,有消息就调用HandlerMessage,没有就阻塞。

 

总结: handler负责发送消息,Looper负责接收handler发送的消息,并把消息回传给handler自己。

        

遗留问题:不new message  用obtain方法 避免重复创建为对象导致内存溢出

hanlder 机制原理和使用

 

 

对你们有帮助,请点赞支持一下。