Handler 是什么?(fromwork)
Handeler是android 给我们提供用来更新UI的一套机制,也是一套消息处理机制,我们可以发送消息,也可以通过他处理消息。
为什么使用Handler?
Handler机制是Android 在设计的时候就封装了一套消息创建。传递,处理机制,如果不遵守这样的机制,就没有办法更新UI信息,就会抛出异常。
Android不允许在非ui线程中更新UI
创建一个handler的时候,他会跟一个默认的线程进行绑定,这个默认线程中会有一个messageQueue,
Handler两个用途
1. Handler 定时的发送一个message 和runnables 对象,
2. 在线程中处理和执行一个action
创建一个应用程序的时候会创建一个进程,在整个activity 中就是一个main 线程(UI线程),是activityThread线程,这个线程会默认的创建一个looper ,这个looper会和 messagequeue 和ui线程有一定的联系。
main 线程,主要是运行一个messgequeue管理顶级的一些应用程序(activity,broadcast,receives,ect)这些顶级的应用程序默认情况下都是创建在activityThread中,这个activityThread就是main 线程。
Handler用法(一)
1.Handler的post(runnable)方法
2.Handler的postDelayed(runnable,long)方法
public class MainActivity extends Activity {
private ImageView imag;
private Handler handler = new Handler();
private int image[] = { R.drawable.image1, R.drawable.image20,
R.drawable.image29 };
private int index;
private myrunnable myrunnable=new myrunnable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imag = (ImageView) findViewById(R.id.imageview1);
handler.postDelayed(myrunnable, 1000);
}
class myrunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
index++;
index=index%3;
imag.setImageResource(image[index]);
handler.postDelayed(myrunnable, 1000);
}
}
}
3.Handler的sendMessage(message)方法
在handler 中更新ui 有arg方法和obj
在线程中调用handler 发送消息 也可以使用message.sendToTarget();方法去发送handler
也可以使用handler.removeCallbacks(runnable); 来移除一个消息(runnable为发送信息的Runnable)
可以通过callback来拦截发送的message当 Boolean为true 以后第二个 handlerMessage就不执行了。
android为什么只能通过handler机制更新ui?
使用Handler机制,最根本的目的是解决多线程并发问题。假如一个人在activity 当中有多个线程去更新UI,并且都没有枷锁机制,那么就会造成更新界面错乱。如果对更新ui 的操作都枷锁处理的话又会使 性能下降。
使用handler机制更新ui都是在主线程的消息队列中去轮询处理的,所以不用去关心多线程问题。
Handler封装了消息的发送(主要包括消息发送给谁)
Looper (轮询;)消息封装的载体
1. 内部包含一个消息队列也就是MessageQueue,所有的Handler发送的消息都走向这个消息队列
2. Looper.Looper方法,就是一个死循环,不断的从MessageQueue取消息,如有有消息就处理消息,没有消息就阻塞
MessageQueue,就是一个消息队列,可以添加消息,并处理消息
Handler也很简单,内部会跟Looper进行关联,也就是说在Handler的内部可以找到Looper,找到了Looper也就找到了MessageQueue 在Handler中发送消息,其实就是向MessageQueue中发送消息
总结:Handler负责发送消息,
Looper负责接收Handler发送的消息,并直接把消息回传给Handler自己,
MessageQueue就是一个存储消息的容器
HandlerThread实现不同线程中的同步
应用程序通过ActivityThread 进行创建,ActivityThread当中负责创建所有的Activity并回调Activity中的所有方法;ActivityThread当中会默认创建一个main线程用于ui更新操作,在创建main 线程的过程中会默认创建一个Looper,在创建Looper 中会默认创建一个MessageQueue 对象。Handler 通过关联取出的消息队列,都是通过默认的ui线程的Looper
当中进行关联的。
Threadlocal用于在线程中保存一些变量信息,有set(looper) 方法 get 方法
自定义与线程相关的handler
class MyThread extends Thread {
public Handler handler;
public Looper looper;
@Override
public void run() {
Looper.prepare();// create looper
looper=Looper.myLooper();//get looper
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
System.out.println(Thread.currentThread().getId());
};
};
Looper.loop();// 循环的处理消息
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView textView = new TextView(this);
textView.setText("hello,handler");
setContentView(textView);
thread = new MyThread();
thread.start();
handler = new Handler(thread.looper){//轮询的是新建的线程
@Override
public void handleMessage(Message msg) {
System.out.println(msg);
}
};
}
主线程与子线程的信息交互?
//主线程和子线程的信息交互
public class FourActivity extends Activity implements OnClickListener {
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
// main handler
Message message = new Message();// 向子线程发送消息
System.out.println("main handler");
threadhandler.sendMessageDelayed(message, 1000);
};
};
private Handler threadhandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_four);
Button stop = (Button) findViewById(R.id.stop);
Button start = (Button) findViewById(R.id.start);
HandlerThread Thread = new HandlerThread("handlerthread");
Thread.start();
threadhandler = new Handler(Thread.getLooper()) {
@Override
public void handleMessage(Message msg) {
// 子线程
Message message = new Message();// 向主线程发送消息
System.out.println("threadhandler");
handler.sendMessageDelayed(message, 1000);
}
};
stop.setOnClickListener(this);
start.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
handler.sendEmptyMessage(1);
break;
case R.id.stop:
handler.removeMessages(1);
// threadhandler.removeMessages(1);
break;
}
}
}