由于android的UI操作并不是线程安全的,android只允许UI线程修改Activity里的UI组件。UI线程就是主线程(Main Thread)。为能让新启动的线程能改变UI组件的属性,需要借助于Handler的消息传递机制。
1.Handler类
Handler类主要有两个作用:
1)在新线程里发送消息;
2)在主线程中获取、处理消息
在新启动的线程里,Handler发送一个消息到Message Queue(消息队列),Looper会从消息队列中取出消息发送给Handler,交由Handler来处理消息(消息队列是先进先出的)。以下是一个实例,通过一个新线程周期性的修改ImageView所显示的图片。
public class MainActivity extends AppCompatActivity { private int[]images={R.drawable.f1,R.drawable.f2,R.drawable.f3,R.drawable.f4}; private int currentImg=0; ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView=(ImageView)findViewById(R.id.image); final Handler myhandler=new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what==0x1233){ imageView.setImageResource(images[currentImg++%images.length]); } } }; new Timer().schedule(new TimerTask() { @Override public void run() { myhandler.sendEmptyMessage(0x1233);//发送一条空信息 } },0,1200); } }
布局文件非常的简单,就只添加了一个ImageView控件。程序中Timer一个定时器,在定时器总调用了TimerTask对象,TimerTask对象的本质就是启动一条新线程。
2.Handler工作原理
1)Looper:每个线程只有一个Looper对象。其loop方法负责读取消息队列的消息,然后将消息发送给发送该消息的Handler。
2)Message Queue:消息队列。消息队列主要是按先进先出的方式存放消息的对象。在创建Looper对象的时候会自动绑定一个MessageQueue对象。
3)Handler:负责发送消息和处理消息。
在线程中使用Handler的过程:
1)在新创建的线程中创建一个Looper对象:Looper.prepare();在上例中主线程会默认的创建一个Looper对象。
2)创建Handler类的子类实例,重写handleMessage()方法;
3)调用Looper的loop方法启动Looper。