Handler 机制主要用来解决Android应用的多线程问题——Android 不允许Activity新启动的线程访问Activity中的组件,这样就导致新启动的线程无法动态改变界面中组件的属性值。但是在实际应用中,我们需要让新启动的线程周期性的更改我们的界面组件显示的内容,因此就需要借助Handler机制来实现。
Handler类中的一些常用方法:
- void handleMessage(Message msg) : 处理消息的方法,通常用于被重写。
- final boolean hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息。
- final boolean (int what,Object object):检查消息队列中是否包含what属性为指定值,且object属性为指定对象的消息。
- 多个重载的Message obtainMessage(): 获取消息
- sendEmptyMessage(int what): 发送空消息。
- final boolean sendEmptyMessageDelayed(int what,long delayMillis):指定多少毫秒之后发送空消息。
- final boolean sendMessage(Message msg):立即发送消息
- final boolean sendMessageDelayed(int what,long delayMillis):指定多少毫秒之后发送消息。
Handler类的两个主要作用
1.在新启动的线程中发送消息。
2.在主线程中获取、处理消息。
我们在新启动的线程中发送消息,然后在主线程中获取、并且处理消息。但是我们新启动的线程何时发送消息,主线程何时获取并处理消息呢?时机显然不好控制,所以Handler 是一个回调的机制。开发者只需要重写Handler类中处理消息的方法,当新启动的线程发送消息时,Handler类中处理消息的方法自动被回调。
简单的示例
public class MainActivity extends AppCompatActivity {
int[] iamgeId = new int[]{
R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e
};
int currentId = 0;
Timer timer;
private ImageView mImage;
private TextView mText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
mImage = (ImageView) findViewById(R.id.iv_show_image);
mText = (TextView) findViewById(R.id.tv_start);
mText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initTimer();
}
});
}
private Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 10086) {
mImage.setImageResource(iamgeId[currentId++]);
}
if (currentId >= 4) {
currentId = 0;
}
}
};
private void initTimer() {
timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what = 10086;
myHandler.sendMessage(msg);
}
};
timer.schedule(task, 1000, 2000);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="test.yihan.testhandler.MainActivity">
<ImageView
android:id="@+id/iv_show_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:scaleType="fitXY" />
<TextView
android:id="@+id/tv_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:background="#33333333"
android:padding="10dp"
android:text="点击开始" />
</LinearLayout>
自己找5个图片去试效果,我们通过在计时器的线程中发消息,去让主线程中的 ImageView 显示不同的图片,来验证了Handler类的简单的用法。