Android Handler学习总结

来源:互联网 发布:数据库视频教程哪个好 编辑:程序博客网 时间:2024/05/21 06:54

一、概述

handler是更新UI的一套机制,消息处理机制,常用方法有post、postDelayed、sendMessage、sendMessageDelayed等,使用handler的根本目的是为了解决多线程并发问题,因为多线程更新UI都没有加锁机制,会导致更新界面错乱。

二、实际案例

1.handler的基本使用
MainActivity.java

package com.czhappy.handlerdemo.activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.czhappy.handlerdemo.R;public class MainActivity extends AppCompatActivity {    private TextView textView;    private ImageView imageView;    private Handler handler1 = new Handler();    private Handler handler2 = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            textView.setText(""+msg.arg1+","+msg.arg2);            textView.setText(""+msg.obj.toString());        }    };    //添加callback根据返回值,是否拦截消息执行    private Handler handler3 = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message msg) {            Toast.makeText(MainActivity.this, "1", Toast.LENGTH_SHORT).show();            //返回true拦截消息            return true;        }    }){        @Override        public void handleMessage(Message msg) {            Toast.makeText(MainActivity.this, "2", Toast.LENGTH_SHORT).show();            super.handleMessage(msg);        }    };    private int images[] = {R.drawable.image1, R.drawable.image2, R.drawable.image3};    private int index;    private MyRunnable myRunnable = new MyRunnable();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        textView = (TextView) findViewById(R.id.textView);        imageView = (ImageView) findViewById(R.id.imageView);        //postDelayed方法        //handler1.postDelayed(myRunnable, 1000);        //sendMessage方法        new Thread(){            @Override            public void run() {                try {                    Thread.sleep(2000);                    Message message = handler2.obtainMessage();                    message.arg1 = 88;                    message.arg2 = 100;                    Person pp = new Person("zhangsan", 23);                    message.obj = pp;                    //发送消息,两种方法均可                    //handler2.sendMessage(message);                    message.sendToTarget();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }.start();    }    class MyRunnable implements Runnable{        @Override        public void run() {            index++;            index = index%3;            imageView.setImageResource(images[index]);            handler1.postDelayed(myRunnable, 1000);        }    }    class Person{        private String name;        private int age;        public Person(String name, int age) {            this.name = name;            this.age = age;        }        @Override        public String toString() {            return "Person{" +                    "name='" + name + '\'' +                    ", age=" + age +                    '}';        }    }    public void stopImageChange(View view){        handler1.removeCallbacks(myRunnable);    }}

2.在子线程中使用handler
SecondActivity.java

package com.czhappy.handlerdemo.activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.widget.TextView;/** * Description: * User: chenzheng * Date: 2017/1/7 0007 * Time: 11:50 */public class SecondActivity extends AppCompatActivity {    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            //此处不要执行耗时操作            Log.e("tag", "UI---------->"+Thread.currentThread());//主线程        }    };    private MyThread thread;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        TextView tv = new TextView(this);        tv.setText("hello");        setContentView(tv);        thread = new MyThread();        thread.start();        try {            thread.sleep(500);        } catch (InterruptedException e) {            e.printStackTrace();        }        thread.handler.sendEmptyMessage(1);        handler.sendEmptyMessage(1);    }    class MyThread extends Thread{        private Handler handler;        @Override        public void run() {            Looper.prepare();            handler = new Handler(){                @Override                public void handleMessage(Message msg) {                    Log.e("tag", ""+Thread.currentThread());//主线程下面的子线程                }            };            Looper.loop();        }    }}

3.关于HandlerThread
ThirdActivity.java

package com.czhappy.handlerdemo.activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.widget.TextView;/** * Description: HandlerThread * User: chenzheng * Date: 2017/1/7 0007 * Time: 14:11 */public class ThirdActivity extends AppCompatActivity{    private HandlerThread thread;    private Handler handler;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        TextView tv = new TextView(this);        tv.setText("hello");        setContentView(tv);        thread = new HandlerThread("handler looper");        handler = new Handler(thread.getLooper()){            @Override            public void handleMessage(Message msg) {                Log.e("tag", ""+thread.currentThread());            }        };    }}

4.主线程与子线程之间相互通信
FourActivity.java

package com.czhappy.handlerdemo.activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import com.czhappy.handlerdemo.R;/** * Description:主线程与子线程之间相互通信 * User: chenzheng * Date: 2017/1/7 0007 * Time: 14:26 */public class FourActivity extends AppCompatActivity {    //创建主线程的    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            Log.e("tag","main handler");            Message message = new Message();            //向子线程发送消息            threadHandler.sendMessageDelayed(message, 1000);        }    };    private Handler threadHandler;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_four);        HandlerThread thread = new HandlerThread("handlerThread");        thread.start();        //创建子线程的handler        threadHandler = new Handler(thread.getLooper()){            @Override            public void handleMessage(Message msg) {                Log.e("tag","thread handler");                Message message = new Message();                //向主线程发送消息                handler.sendMessageDelayed(message, 1000);            }        };    }    public void doSend(View view){        handler.sendEmptyMessage(1);    }    public void doStop(View view){        handler.removeMessages(1);    }}

5.更新UI的四种方式
FiveActivity.java

package com.czhappy.handlerdemo.activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;import com.czhappy.handlerdemo.R;/** * Description:更新UI的几种方式 * User: chenzheng * Date: 2017/1/7 0007 * Time: 15:29 */public class FiveActivity extends AppCompatActivity {    private TextView textView1, textView2, textView3, textView4;    private Handler handler1 = new Handler();    private Handler handler2 = new Handler(){        @Override        public void handleMessage(Message msg) {            textView2.setText("OK");        }    };    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_five);        textView1 = (TextView) findViewById(R.id.textView1);        textView2 = (TextView) findViewById(R.id.textView2);        textView3 = (TextView) findViewById(R.id.textView3);        textView4 = (TextView) findViewById(R.id.textView4);        way1();        way2();        way3();        way4();    }    private void way1() {        new Thread(){            @Override            public void run() {                try {                    Thread.sleep(2000);                    handler1.post(new Runnable() {                        @Override                        public void run() {                            textView1.setText("OK");                        }                    });                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };    }    private void way2(){        handler2.sendEmptyMessage(1);    }    private void way3(){        runOnUiThread(new Runnable() {            @Override            public void run() {                textView3.setText("OK");            }        });    }    private void way4(){        textView4.post(new Runnable() {            @Override            public void run() {                textView4.setText("OK");            }        });    }}

三、总结

  • handler封装了消息的发送
  • Looper消息承装的载体,内部包含消息队列MessgaeQueue
  • Looper.Looper方法是一个死循环,不断的从MessageQueue取消息,有消息就处理消息,没有消息就阻塞
  • MessageQueue是一个消息队列,可以添加消息并处理消息

总结:handler负责消息的发送,Looper负责接收handler发送的消息,并直接把消息回传给handler自己,MessageQueue就是一个存储消息的容器

0 0
原创粉丝点击