Android之Handler详解

handler是什么?

handler是android给我们提供用来更新UI的一套机制,也是一套消息处理机制,我们可以发送消息,也可以通过它处理消息。

 

android中更新ui四种方式:

1、runonui

只能在Activity中使用

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                updateUI();

            }
        }).start();
    }

    private void updateUI() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText("run on UI thread");
            }
        });
    }

2、view.post(runable)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                viewUI();

            }
        }).start();
    }

    private void viewUI() {
        textView.post(new Runnable() {
            @Override
            public void run() {
                textView.setText("view update UI");
            }
        });
    }

3、handler.post()

private  Handler mhandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            
        }
    };
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {
                mhandler.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText("update thread");
                    }
                });
            }
        }).start();
    }

4、handler.sendmessage

private  Handler mhandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            textView.setText(msg.arg1 + msg.arg2 + msg.obj.toString());
        }
    };
    private TextView textView;

    class Person {
        private String name;

        public Person(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(2000);
                    Message msg = new Message();
                    msg.arg1 = 1;
                    msg.arg2 = 2;
                    msg.obj = new Person("Gomez");
                    mhandler.sendMessage(msg);
                    //第二种发送消息方法
//                    msg = mhandler.obtainMessage();
//                    msg.sendToTarget();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

子线程创建Handler

private  Handler mhandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            System.out.println("UIThread:" + Thread.currentThread());
        }
    };
    private TextView textView;
    private MyThread myThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        myThread = new MyThread();
        myThread.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myThread.handler.sendEmptyMessage(1);
        mhandler.sendEmptyMessage(1);
    }

    class MyThread extends Thread {
        Handler handler;

        @Override
        public void run() {
            super.run();
            //初始化looper
            Looper.prepare();
            handler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    System.out.println("currentThread:" + Thread.currentThread());
                }
            };
            //循环读取消息
            Looper.loop();
        }
    }


}

运行效果:

HandlerThread

  • HandlerThread本质上是一个线程类,它继承了Thread;
  • HandlerThread有自己的内部Looper对象,可以进行looper循环;
  • 通过获取HandlerThread的looper对象传递给Handler对象,可以在handleMessage方法中执行异步任务。
  • 创建HandlerThread后必须先调用HandlerThread.start()方法,Thread会先调用run方法,创建Looper对象。


通过HandlerThread可以避免自定义线程中很多空指针问题,如上例如果不在主线程中加入延时,那个我们拿到的子线程的handler是为空的。

 private HandlerThread handlerThread;
    private Handler handler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        handlerThread = new HandlerThread("handler thread");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                System.out.println("current thread" + Thread.currentThread());
            }
        };
        handler.sendEmptyMessage(1);
    }
    

在HandlerThread拿到的Looper都是安全的,在内部已经处理多线程同步;

这样所有handleMessage都是在子线程中执行,用HandlerThread模拟一些异步任务,主线程给子线发送消息,子线程执行一些耗时操作,比如一些下载图片,访问服务器都可以这样去执行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章