在Android中不允许Activity新启动的线程访问该Activity里的UI组件
而一般一个activity中需要由多个线程来完成不同任务,然后更新UI;比如我们使用手机在线听音乐,它要一边缓冲一边播放,同时还要显示播放进度,这些都需要更新UI,而又很难在一个线程中完成,所以就可以通过Handler()来完成这些更新,通过创建一个handler实例,它会被绑定到创建它的线程中(通常即为主线程),既然在主线程中,那么就可以很好的完成主线程UI的更新;不同线程将其要执行的内容添加到handler的消息队列中去
(1):将要执行的内容重写到run()方法中,然后将Runnable()接口封装成Message加入到handler的消息队列中(由post()方法完成);
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
//由于不需要处理Message,也即不需要处理handleMessage()
Handler h = new Handler();
//这里post()方法内部依然是将updatethread封装成Message加入到Handler的消息队列中,在handler所相连的线程(这里是在主线程)中去执行,因此和使用handleMessage()没有本质的区别。
h.post(updatethread);
}
通过Runnable接口实现实现线程(将要执行的对象写在要执行的run方法当中) ,该类使用匿名内部类的方式进行声明
Runnable updatethread =new Runnable(){
@Override
public void run() {
while(true){
i=i+10;
try{
//线程休眠即为休眠主线程了,因此可以发现activity短暂无法操作
Thread.sleep(2000);
}
catch(Exception e){
e.printStackTrace();
}
if(i==100)
i=0;
//更新进度条
pressbar1.setProgress(i);
}}
};
这个线程操作是在主线程中完成的,因此run()中出现Thread.sleep(2000),即为主线程休眠2S,因此在调试中会发现整个主线程休眠无法操作,因此这种方法内只适合执行尽量简短的操作(比如在这里将Thread.sleep(2000)删掉就可以接受,因为run()中的内容耗时少,不会影响主线程),否则会影响整个主线程。
(2):通过在子线程中将要传送的数据内容以Message的方式加入到handler的消息队列中
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
//通过handleMessage()对消息队列中的Message进行分析处理,这里简单示例,不做分析
Handler h = new Handler(){
@Override//一旦队列中有消息,就会进行分析处理,处理完移除,处理下一个
public void handleMessage(Message msg){
//这里仅有一个Message,msg.arg1的值就是i的值
pressbar1.setProgress(msg.arg1);
};
}
通过Runnable接口实现实现线程(将要执行的对象写在要执行的run方法当中) ,该类使用匿名内部类的方式进行声明
Runnable updatethread =new Runnable(){
@Override
public void run() {
i = i + 10 ;
if(i==100)
i=0;
Message msg = h.obtainMessage();
msg.arg1 = i ;
//加入到队列中去
h.sendMessage(msg);
}};
在Android中,直接从新启动的线程访问UI组件是不允许的。本文介绍了如何通过Handler和Runnable接口来实现线程间通信并更新UI。一种方式是将Runnable对象通过post()方法加入消息队列,另一种是在子线程中创建Message并发送到Handler的消息队列,然后在主线程中处理更新UI的任务。


被折叠的 条评论
为什么被折叠?



