android基础--Handler,Loop,MessageQueue

Handler可以声明在主线程可以声明在新开的线程,只不过在新开的线程定义handler要自己创建一个Looper对象,并通过prepare()启动它。在ui线程中系统已经初始化了一个Looper对象。

先看定义在主线程的情况:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Handler handler = new Handler(){
            public void handleMessage(Message msg){
                if(msg.what==123){
                    Bundle bundle=msg.getData();
                    int i=bundle.getInt("i");
                    Toast.makeText(getApplicationContext(),"handler 测试成功 "+i,Toast.LENGTH_SHORT).show();
                }
            }
        };

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                int i=5;
                Message message=new Message();
                Bundle bundle=new Bundle();
                bundle.putInt("i",i);
                message.setData(bundle);
                message.what=123;
                handler.sendMessage(message);
            }
        },0,1200);

这里定义了一个Timer来启动一条新线程以周期性的执行任务。

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

现在来看在子线程定义handler的情况:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button=(Button)findViewById(R.id.btn);
        mes msg=new mes("来自主线程");
        final Message message=new Message();
        message.what=123;
        Bundle bundle=new Bundle();
        bundle.putSerializable("msg", msg);
        message.setData(bundle);
        final MyThread myThread=new MyThread();
        myThread.start();


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myThread.handler.sendMessage(message);
            }
        });



    }

    class MyThread extends Thread{
        public Handler handler;
        public void run(){
            Looper.prepare();
            handler=new Handler(){
                public void handleMessage(Message message){
                    if(message.what==123){
                        Bundle bundle=message.getData();
                        mes msg=new mes();
                        msg=(mes)bundle.getSerializable("msg");
                        Toast.makeText(MainActivity.this,"测试成功 "+msg.getText(),Toast.LENGTH_SHORT).show();
                    }
                }
            };
            Looper.loop();
        }
    }

mes类

public class mes implements Serializable{
    String text;

    public mes() {
    }

    public mes(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

这里值得注意的是如果不设个按钮事件,而是直接将myThread.handler.sendMessage(message);写在myThread.start()后面会报出空指针异常。

发布了21 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/coding_man_xie/article/details/49859109
今日推荐