Android中的Handler使用方式

来源:互联网 发布:js需要做保护层吗 编辑:程序博客网 时间:2024/06/05 14:12

一、什么是Handler



Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制。每个Hanlder都关联了一个线程,每个线程内部都维护

一个消息队列MessageQueue,这样Handler实际上也就关联了一个消息队列。可以通过Handler将Message和Runnable对象发

送到该Handler所关联线程的MessageQueue(消息队列)中,然后该消息队列一直在循环拿出一个Message,对其进行处理,处

理完之后拿出下一个Message,继续进行处理,周而复始。当创建一个Handler的时候,该Handler就绑定了当前创建Hanlder的线

程。从这时起,该Hanlder就可以发送Message和Runnable对象到该Handler对应的消息队列中,当从MessageQueue取出某个

Message时,会让Handler对其进行处理。



二、Handler作用



Handler可以用来在多线程间进行通信,在另一个线程中去更新UI线程中的UI控件只是Handler使用中的一种典型案例,除此之外,

Handler可以做很多其他的事情。每个Handler都绑定了一个线程,假设存在两个线程ThreadA和ThreadB,并且HandlerA绑定了

 ThreadA,在ThreadB中的代码执行到某处时,出于某些原因,我们需要让ThreadA执行某些代码,此时我们就可以使用

Handler,我们可以在ThreadB中向HandlerA中加入某些信息以告知ThreadA中该做某些处理了。由此可以看出,Handler是

Thread的代言人,是多线程之间通信的桥梁,通过Handler,我们可以在一个线程中控制另一个线程去做某事。



三、主线程中的Handler



下面的Handler是主线程中的Handler,因为其是在主线程中创建的,所以默认就是和主线程进行绑定的,通过一个延时的POST方法来进行UI的循环更新。

public class MainActivity extends AppCompatActivity {    private Handler handler = new Handler();    private  int images[] = new int[]{R.drawable.im1, R.drawable.im2, R.drawable.im3};    private int index = 0;    private MyRunnable myRunnable = new MyRunnable();    private ImageView im_debug;    class MyRunnable implements Runnable{        @Override        public void run() {            index++;            index = index % 3;            im_debug.setImageResource(images[index]);            handler.postDelayed(myRunnable, 1000);        }    }        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        im_debug = (ImageView) findViewById(R.id.im_debug);        handler.postDelayed(myRunnable, 1000);    }    }



四、两种Handler发消息



如下是Handler的两种绑定方式,一个和主线程进行绑定,一个和子线程进行绑定,这两个分别向主线程的Handler和子线程的

Handler发消息就可以得到得到其线程的ID,并且子线程中建立Looper

public class SecondActivity extends Activity {    private MyThread thread;    //默认是在主线程中执行    public Handler uiHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            System.out.print("UI-----"+Thread.currentThread());        }    };    //在子线程中执行    class MyThread extends Thread{        public Handler hander;        public void run(){            Looper.prepare();            hander = new Handler(){                @Override                public void handleMessage(Message msg) {                    System.out.print("CurrentID = "+Thread.currentThread());                }            };            Looper.loop();        }    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        TextView tv = new TextView(this);        tv.setText("hello Handler");        setContentView(tv);        thread = new MyThread();        thread.start();        try {            Thread.sleep(500);        } catch (InterruptedException e) {            e.printStackTrace();        }        //向子线程发消息        thread.hander.sendEmptyMessage(1);        //向主线程发消息        uiHandler.sendEmptyMessage(1);    }    }



五、HandlerThread使用



HandlerThread建立的线程是在子线程中的,建立子线程的Handler的时候要绑定一个Looper

public class ThreeActivity extends Activity {    private HandlerThread thread;    private Handler handler;    private static final String TAG = "ThreeActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        TextView tv = new TextView(this);        tv.setText("Handler Thread Handler");        setContentView(tv);        //HandlerThread中使用了同步机制了        thread = new HandlerThread("handlerThread");        thread.start();        //如果looper为空,就处于等待的状态,直到Handler可以拿到looper对象        //这个是子线程的Handler        handler = new Handler(thread.getLooper()){            @Override            public void handleMessage(Message msg) {                System.out.print("当前线程:"+Thread.currentThread());                Log.i(TAG, "当前线程"+Thread.currentThread());            }        };        handler.sendEmptyMessage(1);    }}



六、Handler更新UI



Handler提供了两种方式解决我们在本文一开始遇到的问题(在一个新线程中更新主线程中的UI控件),一种是通过post方法,一

种是调用sendMessage方法。

public class FiveActivity extends Activity {    private TextView tv_five;    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            tv_five.setText("OK了方法2");        }    };    public void handler1(){        //这个是第一种方式来更新UI        //本质上也是发送message        handler.post(new Runnable() {            @Override            public void run() {                tv_five.setText("OK了方法1");            }        });    }    public void handler2(){        handler.sendEmptyMessage(1);    }    public void handler3(){        //内部还是通过UI机制        runOnUiThread(new Runnable() {            @Override            public void run() {                tv_five.setText("OK了方法3");            }        });    }    public void handler4(){        //        tv_five.post(new Runnable() {            @Override            public void run() {                tv_five.setText("OK了方法4");            }        });    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_five);        tv_five = (TextView) findViewById(R.id.tv_five);        new Thread(){            @Override            public void run() {                try {                    Thread.sleep(2000);                    //分别在此处调用不同的更新UI的方法                    handler4();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }.start();    }}

其实最常用的还是那两种方式,虽然Message的构造函数式public的,我们还可以通过Message.obtain()或

Handler.obtainMessage()来获得一个Message对象(Handler.obtainMessage()内部其实调用了Message.obtain())。 







详细的介绍请参考下面两篇文章,写的很好:


http://blog.csdn.net/iispring/article/details/47115879

http://blog.csdn.net/iispring/article/details/47180325



1 0