1 Handler是什么?
* Handler:用来更新UI(主线程)的一套机制,也是一套消息处理机制,我们可以发送信息,也可以通过它来处理消息。
* 比如最常见的Activity的生命周期:它的回调方法都是通过Handler机制去发送消息的,根据不同的Message来做相应的分支处理。
2 为什么要使用Handler?
* 因为android在设计的时候就封装了一套消息创建,传递,处理机制,如果不遵循这样的机制就没有办法来跟新UI的信息,就会抛出异常。(不能在一个非UI线程中跟新UI)。
* 一个Handler实例其实绑定了一个关联的thread线程和这个线程的message queue;handler会将message和runnable对象发送到它所关联的message queue中去, 同时它也会执行从message queue中出来的message和runnable。
* 3 handler的四种使用的方法:
* sendMessage
* sendMessageDelayed
* post(Runnable)
* postDelayed(Runnable,long)
*
图片轮播
MainActivity.class
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private Handler handler = new Handler();
private int Images[] = {R.drawable.imga, R.drawable.imgb, R.drawable.imgc};
private int index;//索引,指示照片的位置
private MyRunnable myRunnable = new MyRunnable();//创建一个Runnable对象
/**
* 创建一个Runnable
*/
class MyRunnable implements Runnable {
@Override
public void run() {
index++;
index = index % 3;
imageView.setImageResource(Images[index]);//让ImageView设置轮播的图片
handler.postDelayed(myRunnable, 1000);//每隔1秒去执行myRunnable方法,不断轮播图片,第一个参数是要执行的Runnable对象
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.iv_picture);
handler.postDelayed(myRunnable, 1000);
}
}
4 sendMessage方法
//需要Handler的Message方法
private Handler handler = new Handler() { //重写HandleMessage来接收消息,怎么发送一个消息?要在Created方法里面new 出一个线程在里面发送消息
@Override
public void handleMessage(Message msg) {
textView.setText(" " + msg.arg1+ " --- "+msg.arg2);//更新TextView里面的文字
super.handleMessage(msg);
}
};
在onCreate方法里面创建一个线程:
new Thread() {
@Override
public void run() {
try {
Thread.sleep(2000);
//要发送消息,那就要先创建一个Message
Message message = new Message();
message.arg1 =88;
message.arg2 =888;
handler.sendMessage(message);//调用Handler的sendMessage方法来发送消息给handleMessage来处理消息
} catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}.start();//不要忘记调用start方法,否者线程里面的run方法不会执行
调用Message的obj方法来发送比较多的数据,来发送Message的数据载体:
现在内部创建一个Person类:
//创建一个Person类
class Person {
public int age;
public String name;
//调用toString方法输出name 和age
@Override
public String toString() {
return "name=" + name + "age=" + age;
}
}
然后在线程里面new一个Person对象:
new Thread() {
@Override
public void run() {
try {
Thread.sleep(2000);
//要发送消息,那就要先创建一个Message
Message message = new Message();
Person person = new Person();
person.age = 22;
person.name = "xiaoxjxoaxm";
message.obj = person;//调用Message的obi方法来接收person的信息
handler.sendMessage(message);//调用Handler的sendMessage方法来发送消息给handleMessage来处理消息
} catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}.start();
更新TextView里面的数据:
private Handler handler = new Handler() {
//重写HandleMessage来接收消息,怎么发送一个消息?要在Created方法里面new 出一个线程在里面发送消息
@Override
public void handleMessage(Message msg) {
textView.setText(" " + msg.obj);//更新TextView里面的文字
super.handleMessage(msg);
}
};
有时候不要创建一个Message对象,直接调用系统的Message的obtainMessage()方法
new Thread() {
@Override
public void run() {
try {
Thread.sleep(2000);
//有时候不必创建一个Message对象,而是调用系统的Message对象
Message message=handler.obtainMessage();//获取Message对象
Person person = new Person();
person.age = 22;
person.name = "xiaoxjxoaxm";
message.obj = person;//调用Message的obi方法来接收person的信息
handler.sendMessage(message);//调用Handler的sendMessage方法来发送消息给handleMessage来处理消息
} catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}.start();
有时候不调用 handler.sendMessage(message)来发送消息,还可以调用 message.sendToTarget()来发送消息。target就是一个Handler,它其实就是调用sendMessage来发送消息。
handler.removeCallbacks();//里面传入一个Runnable对象,来移除消息
new Handler(Callback )的时候里面的那个回调方法的作用就是,方便handler内部信息的拦截(当这个消息符合我们的拦截的对象),当callback的handlerMessage方法的返回值为true的时候,handler本身的那个handlerMessage方法将得不到回调的信息,所以第二个handlerMessage方法并不会执行。如果那个返回值为false的话,第二个方法就会得到执行。
private Handler handler=new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Toast.makeText(getApplicationContext(),""+2,Toast.LENGTH_SHORT).show();
return false;
}
}){
@Override
public void handleMessage(Message msg) {
Toast.makeText(getApplicationContext(),""+1,Toast.LENGTH_SHORT).show();
}
};