一、前言
我们都知道不能用子线程来更新UI,否则可能引起主线程阻塞造成ApplicationNotResponseException。一般我们可以通过Handler机制,在子线程中不断给Handler对象发送消息来达到动态更新UI的目的。另外,也可以通过Service+BroadcastReceiver的方式来实现动态更新UI甚至定时更新UI ,功能更为广泛和强大。小弟初来乍道,讲得不好还望海涵 ^_^
二、原理
好了,切入正题。
很多时候我们希望实时动态地更新UI,如数字时钟,每一秒都有变化;还有每隔一段时间更新的要求,如天气预报,适合以小时间隔来更新。以下是我正在做的一个小项目的效果图,之后就按图中的效果来讲解。
左边是一个ImageView控件来显示天气图片,中间上下两个TextView分别显示天气情况和温度,都属于天气信息,每小时联网更新一次;右边上下两个TextView分别显示日期和时间,每秒更新一次。
Service+BroadcastReceiver的基本思路:在需要被更新的UI所在的Activity中开启Service,并在该Activity中注册广播过滤器和广播接收器,以接收Service发送的广播;在Service中定时发送广播;广播接收器接收到Service一定时间发送的广播来执行更新UI动作。
三、代码及注释
看代码前,我先贴出项目的类的结构,因为我在看别人博客这样做的时候,会更明晰一些:)
每个类的功能应该能见文知意,若不明白后面会详解。先讲实时动态更新时间,相对简单。
(一)实时动态更新时间
在需要被更新的UI所在的Activity(我这里是MainActivity)的onCreate()方法里开启服务:
/**
* 启动更新时间服务
*/
private void startTimeService() {
Intent timeService = new Intent(this, UpdateTimeService.class);
startService(timeService);
}
另外,请记得在Activity的onDestroy()方法中停止服务:
@Override
protected void onDestroy() {
stopService(new Intent(MainActivity.this, UpdateTimeService.class));//停止更新时间服务
super.onDestroy();
}
服务 UpdateTimeService.java:
package app.weather_date;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class UpdateTimeService extends Service {
@Override
public void onCreate() {
super.onCreate();
//定时器每隔1秒发送一次广播
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Intent timeIntent = new Intent();
timeIntent.setAction("TIME_CHANGED_ACTION");//自定义Action
sendBroadcast(timeIntent); //发送广播
}
}, 0, 1000);{ //每隔1秒
<s