在Android中提供了一种异步回调机制Handler,我们可以在完成一个很长时间的任务后做出相应的通知。
handler的基本使用:在主线程中使用起来很简单,new一个handler对象并实现handleMessage的方法,在handleMessage中提供收到信息后得到处理方法。
我们写一个在子线程中更新UI的小程序
布局.xml代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="change" />
</LinearLayout>
布局里有两个view,点击Button时改变TextView的内容。
下面是MainAtivity.java中的代码:
public class MainActivity extends Activity {
private TextView textView;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
new Thread(new Runnable() {
@Override
public void run() {
textView.setText("123");
}
}).start();
break;
default:
break;
}
}
});
}
}
运行程序时会出现错误,由此证实了Android不允许在子线程中更新UI,但有些时候必须在子线程中执行耗时操作,对于这种情况,Android提供了一套异步消息处理机制,完美的解了在子线程中更新UI的操作。
下面修改MainActivity.java中的代码,实现在子线程更新UI:
代码如下:
public class MainActivity extends Activity {
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
// textView.setText(" "+msg.obj);
switch (msg.what) {
case 1:
textView.setText("I Love Android");
break;
default:
break;
}
};
};
private TextView textView;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
new Thread(new Runnable() {
@Override
public void run() {
// textView.setText("123");
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}).start();
break;
default:
break;
}
}
});
}
}
这下就能在子线程中更新UI。
这里我们引入了 message.what = 1; 1用于表示更新TextView的动作。然后新增了一个Handler对象,重写handleMessage这个方法,在这里对具体的Message进行处理。
现在来看一下点击事件,我们并没有在子线程中直接更新UI,而是创建了一个Message的对象,并将它的what字段指定为1,然后调用Handler的sendMessage()的方法将这条Message发送出去。Handler就会收到这条Message,并在handleMessage()方法中对它进行处理。