出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题。为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件。
Handle类的主要作用:
- 在新启动的线程中发送信息;
- 在主线程中获取、处理信息。
handle的两个重要方法:
void handleMessage(Message msg):处理消息的方法
sendEmptyMessage(int what):发送空信息。what表示默认的信息代码,用来区分信息的唯一性。
final Handler myHandler = new Handler () { @Override public void handleMessage(Message msg) { if (msg.what == 0x1222) { } } };------------------------------------------------------------------------------------------------
在开发中我们有时会有这样的需求,即在固定的每隔一段时间执行某一个任务。比如UI上的控件需要随着时间改变,我们可以使用Java为我们提供的计时器的工具类,即Timer和TimerTask。
Timer是一个普通的类,其中有几个重要的方法;而TimerTask则是一个抽象类,其中有一个抽象方法run(),类似线程中的run()方法,我们使用Timer创建一个他的对象,然后使用这对象的schedule方法来完成这种间隔的操作。
schedule方法有三个参数
第一个参数就是TimerTask类型的对象,我们实现TimerTask的run()方法就是要周期执行的一个任务;
第二个参数有两种类型,第一种是long类型,表示多长时间后开始执行,另一种是Date类型,表示从那个时间后开始执行;
第三个参数就是执行的周期,为long类型。
schedule方法还有一种两个参数的执行重载,第一个参数仍然是TimerTask,第二个表示为long的形式表示多长时间后执行一次,为Date就表示某个时间后执行一次。
Timer是一个普通的类,其中有几个重要的方法;而TimerTask则是一个抽象类,其中有一个抽象方法run(),类似线程中的run()方法,我们使用Timer创建一个他的对象,然后使用这对象的schedule方法来完成这种间隔的操作。
schedule方法有三个参数
第一个参数就是TimerTask类型的对象,我们实现TimerTask的run()方法就是要周期执行的一个任务;
第二个参数有两种类型,第一种是long类型,表示多长时间后开始执行,另一种是Date类型,表示从那个时间后开始执行;
第三个参数就是执行的周期,为long类型。
schedule方法还有一种两个参数的执行重载,第一个参数仍然是TimerTask,第二个表示为long的形式表示多长时间后执行一次,为Date就表示某个时间后执行一次。
Timer就是一个线程,使用schedule方法完成对TimerTask的调度,多个TimerTask可以共用一个Timer,也就是说Timer对象调用一次schedule方法就是创建了一个线程,并且调用一次schedule
后TimerTask是无限制的循环下去的,使用Timer的cancel()停止操作。当然同一个Timer执行一次cancel()方法后,所有Timer线程都被终止。
new Timer().schedule( new TimerTask(){ //TimerTask类型的对象,TimerTask的run()方法是要周期执行的一个任务 @Override public void run() { currentColor ++; if (currentColor >= 6) currentColor = 0; Message m = new Message(); m. what = 0x1122; handler.sendMessage(m); } }, 0 , //表示多长时间后开始执行 100//执行的周期 );
【example】
霓虹灯:public class FrameLayoutTest extends Activity { private int currentColor = 0; final int[] colors = new int[] { R.color.color7, R.color.color6, R.color.color5, R.color.color4, R.color.color3, R.color.color2, R.color.color1, }; final int[] names = new int[] { R.id.View01, R.id.View02, R.id.View03, R.id.View04, R.id.View05, R.id.View06, R.id.View07 }; TextView[] views = new TextView[7]; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); for (int i = 0 ; i < 7 ; i++) { views[i] = (TextView)findViewById(names[i]); } final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if(msg.what == 0x1122) { for(int i = 0 ; i < 7 - currentColor ; i++) { views[i].setBackgroundResource(colors[i + currentColor]); } for(int i = 7 - currentColor , j = 0 ; i < 7 ; i++ ,j++) { views[i].setBackgroundResource(colors[j]); } } } }; new Timer().schedule(new TimerTask() { @Override public void run() { currentColor++; if(currentColor >= 6) { currentColor = 0; } Message m = new Message(); m.what = 0x1122; handler.sendMessage(m); } }, 0 , 100); } }
自动播放动画:
public class HandlerTest extends Activity { int[] imageIds = new int[] { R.drawable.haed_danya, R.drawable.haed_fanse, R.drawable.haed_fugu, R.drawable.haed_gudian, R.drawable.haed_houqingchu }; int currentImageId = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final ImageView show = (ImageView)findViewById(R.id.show); final Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0x1222) { show.setImageResource(imageIds[currentImageId++]); if (currentImageId >= 4) { currentImageId = 0; } } } }; new Timer().schedule(new TimerTask() { @Override public void run() { Message msg = new Message(); msg.what = 0x1222; myHandler.sendMessage(msg); } }, 0 , 100); } }