概念
- 更新UI机制,也是消息处理机制;可以发送消息,也可以处理消息.
使用
- 错误的更新ui例子
package com.example.sujinming.qumiao;
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
public class testHandler extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_handler);
textView = (TextView)findViewById(R.id.textView);
new Thread() {
public void run(){
try {
Thread.sleep(1000);
textView.setText("123");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
抛出异常
ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
- 成功更新实例
package com.example.sujinming.qumiao;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.EditText;
import android.widget.TextView;
public class testHandler extends Activity {
private TextView textView;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_handler);
textView = (TextView)findViewById(R.id.textView);
new Thread() {
public void run(){
try {
Thread.sleep(1000);
handler.post(new Runnable() {
@Override
public void run() {
textView.setText("123");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
常用方法
- handlerPostDelay()
- handlerMessage()实例
package com.example.sujinming.qumiao;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class testHandler extends Activity {
private TextView textView;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
textView.setText(""+msg.arg1);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_handler);
textView = (TextView)findViewById(R.id.textView);
new Thread() {
public void run(){
try {
Thread.sleep(2000);
Message message = new Message();
message.arg1 = 88;
handler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
注:(1)除了使用arg1,arg2参数外,还可以使用obj作为参数传送
(2)也可以使用handler.obtainMessage()获得Message对象;也可以不使用handler发送消息,而使用message.sendToTarget();代替
- handler.removeCallbacks(runnable);
- 消息截获
Handler handler = new Handler(new Callback(){
public boolean handlerMessage(Message msg) {
//截获handler发送的消息,如果设置为true,之后的handlermessage就部执行了
return false;
}
}) {
public void handlerMessage(Message msg) {
}
}
使用handler更新ui的原因
- 解决多线程的并发问题.
- 举例:多个线程更新ui,并且没有加锁机制,则会造成界面混乱.如果进行加锁,则会导致性能下降.因此android 提供了handler,不用取关心多线程问题,所有的更新ui的操作都是在主线程的消息队列中轮询处理的.
与线程相关的Handler
- 实例
class MyThread extends Thread{
public Handler handler;
public Looper looper;
public void run(){
Looper.prepare();
looper = Looper.myLooper();
handler = new Handler(){
public void handleMessage(msg) {
}
}
}
Looper.loop();
}
- 使用HandlerThread避免handler的空指针问题,解决多线程并发问题
主线程给子线程发送消息
更新ui的方法
- runOnUiThread
- handler.post
- handler.sendMessage
- view post
非UI线程更新ui的情况
- viewRootImp在activity的onResume()中进行创建
- 因为[检查更新UI是否在主线程中]的ViewRootImpl对象是在Activity的onResume方法中被创建出来的.所在在onCreate中起一个线程来更新UI可能会正常运行的
ps
推荐一篇关于handler的博客handler
看到这里,android的基本知识已经差不多了,终于可以继续写我的应用了,加油,
趣喵