Android平台不允许Activity新启动的线程访问该Activity里的界面组件,这样就会导致新线程无法动态改变界面组件的属性值,借助Handler的消息传递能够实现新启动的线程周期性的改变界面组件的属性值。
Handler类主要作用是在新启动的线程中发送消息,在主线程中获取处理消息。
Handler类包含如下方法用于发送和处理消息:
void handleMessage(Message msg):处理消息的方法通常被重写
final boolean hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息
final boolean hasMessage(int what, Object object):检查消息队列中是否包含what属性为指定值且object为指定对象的消息
sendEmptyMessage(int what):发送空消息
final boolean sendEmptyMessageDelayed(int what, long delayMillis):指定延迟多少毫秒之后发送空消息
final boolean sendMessage(Message msg):发送消息
final boolean sendMessageDelayed(Message msg, long delayMillis):延迟发送消息
下面的示例中主界面定义了一个ImageView组件,定义一个定时器,周期的发送消息,主线程收到消息之后修改ImageView的属性,实现周期性的修改显示的图片,java代码如下:
package com.example.handlerexample;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
public class MainActivity extends Activity {
int [] imageIds = new int[]
{
R.drawable.draw1,
R.drawable.draw2,
R.drawable.draw3,
R.drawable.draw4,
R.drawable.draw5,
R.drawable.draw6
};
int currentImageId = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView show = (ImageView)findViewById(R.id.iv01);
final Handler myHandler = new Handler()
{
public void handleMessage(Message msg)
{
if (msg.what == 0x1233)
{
// 修改显示的图片
show.setImageResource(imageIds[currentImageId++]);
if (currentImageId >= 6)
{
currentImageId = 0;
}
}
}
};
new Timer().schedule(new TimerTask()
{
@Override
public void run() {
// TODO Auto-generated method stub
// 新线程无法访问Activity界面组件
Message msg = new Message();
msg.what = 0x1233;
myHandler.sendMessage(msg);
}
}, 0, 800);
}
}
draw1-6为drawable目录下的6张图片文件,界面的ImageView组件如下:
<ImageView
android:id="@+id/iv01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>