【Android应用实例之四】计时器之通过Service&BroadcastReceiver实现UI动态更新
2011-10-04 21:37
736 查看
[b]转载请注明出处,原文网址:/article/1355246.html 作者:张燕广[/b]
实现的功能:计时器。
实现的思路:1)后台Service每隔1秒发送广播通知时间已发生变化;
2)UI层(Activity)通过BroadcastReceiver接收到广播,更新显
示的时间。
关键技术点:Service的应用、BroadcastReceiver的应用
说明:1)Activity与通过startService方法启动的Service之间无法直接进行通信,但是借助BroadcastService可以实现两者之间的通信。
2)实现计时器的方式有很多种,比如通过Thread的sleep等,此处只是演示Service与BroadcastService的组合应用(可以将Service中获取当前时间的操作想象为非常耗时的操作,所以不宜直接在UI层来做)。
3)此处演示的Service与BroadcastService的组合是“单向通信”即:UI层只是被动接收Service发来的广播,而没有主 动发送广播控制后台Service。下一篇文章将会编写一个实例进行演示“双向通信”。
第一步:新建一个工程,命名为DynamicUI,Activity命名为DynamicUIActivity。
修改布局文件main.xml,代码如下:
DynamicUIActivity类代码如下:
第二步:实现自定义BroadcatReceiver类UITimeReceiver,负责接收从后台Service发送过来的广播,获取最新时间数据后更新UI层组件。本类最好作为UI层(Activity)的内部类,此处将其作为外部类实现(通过xml文件配置注册BroadcatReceiver,如果是内部类如何通过xml文件配置目前没找到),有意显示如此做导致代码不够优雅。
UITimeReceiver代码如下:
第三步:实现自定义Service类TimeService,其代码如下:
第四步:修改AndroidManifest.xml文件,代码如下:
第五步:运行程序,效果如下:
实现的功能:计时器。
实现的思路:1)后台Service每隔1秒发送广播通知时间已发生变化;
2)UI层(Activity)通过BroadcastReceiver接收到广播,更新显
示的时间。
关键技术点:Service的应用、BroadcastReceiver的应用
说明:1)Activity与通过startService方法启动的Service之间无法直接进行通信,但是借助BroadcastService可以实现两者之间的通信。
2)实现计时器的方式有很多种,比如通过Thread的sleep等,此处只是演示Service与BroadcastService的组合应用(可以将Service中获取当前时间的操作想象为非常耗时的操作,所以不宜直接在UI层来做)。
3)此处演示的Service与BroadcastService的组合是“单向通信”即:UI层只是被动接收Service发来的广播,而没有主 动发送广播控制后台Service。下一篇文章将会编写一个实例进行演示“双向通信”。
第一步:新建一个工程,命名为DynamicUI,Activity命名为DynamicUIActivity。
修改布局文件main.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FFFFFF"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="当前时间: " /> <TextView android:id="@+id/time" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv" /> </RelativeLayout>
DynamicUIActivity类代码如下:
package com.zyg.demo.service.dynamicui; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.os.Bundle; import android.widget.TextView; public class DynamicUIActivity extends Activity { public static String TIME_CHANGED_ACTION = "com.zyg.demo.service.dynamicui.action.TIME_CHANGED_ACTION"; public static TextView time = null; private Intent timeService = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化UI initUI(); System.out.println("initUI"); //注册广播-方法1 /* * 配置 * <receiver android:name=".UITimeReceiver"> <intent-filter> <action android:name="com.zyg.demo.service.dynamicui.action.TIME_CHANGED_ACTION"/> </intent-filter> </receiver> */ //注册广播-方法2 //注册广播,监听后台Service发送过来的广播 //registerBroadcastReceiver(); //启动服务,时间改变后发送广播,通知UI层修改时间 startTimeService(); } public TextView getTimeTextView(){ return time; } /** * 初始化UI */ private void initUI(){ time = (TextView)findViewById(R.id.time); time.setTextColor(Color.RED); time.setTextSize(15); } /** * 注册广播 */ private void registerBroadcastReceiver(){ UITimeReceiver receiver = new UITimeReceiver(); IntentFilter filter = new IntentFilter(TIME_CHANGED_ACTION); registerReceiver(receiver, filter); } /** * 启动服务 */ private void startTimeService(){ timeService = new Intent(this,TimeService.class); this.startService(timeService); } @Override protected void onDestroy() { super.onDestroy(); //停止服务 stopService(timeService); } }
第二步:实现自定义BroadcatReceiver类UITimeReceiver,负责接收从后台Service发送过来的广播,获取最新时间数据后更新UI层组件。本类最好作为UI层(Activity)的内部类,此处将其作为外部类实现(通过xml文件配置注册BroadcatReceiver,如果是内部类如何通过xml文件配置目前没找到),有意显示如此做导致代码不够优雅。
UITimeReceiver代码如下:
package com.zyg.demo.service.dynamicui; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; /** * 自定义的UI层BroadcastReceiver,负责监听从后台Service发送过来的广播,根据广播数据更新UI * @author zhangyg */ public class UITimeReceiver extends BroadcastReceiver{ private DynamicUIActivity dUIActivity = new DynamicUIActivity(); @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(DynamicUIActivity.TIME_CHANGED_ACTION.equals(action)){ Bundle bundle = intent.getExtras(); String strtime = bundle.getString("time"); //此处实现不够优雅,为了在UITimeReceiver中使用DynamicUIActivity中的TextView组件time,而将其设置为public类型, //更好的实现是将UITimeReceiver作为DynamicUIActivity的内部类 dUIActivity.time.setText(strtime); } } }
第三步:实现自定义Service类TimeService,其代码如下:
package com.zyg.demo.service.dynamicui; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class TimeService extends Service{ private String TAG = "TimeService"; private Timer timer = null; private SimpleDateFormat sdf = null; private Intent timeIntent = null; private Bundle bundle = null; @Override public void onCreate() { super.onCreate(); Log.i(TAG,"TimeService->onCreate"); //初始化 this.init(); //定时器发送广播 timer.schedule(new TimerTask() { @Override public void run() { //发送广播 sendTimeChangedBroadcast(); } }, 1000,1000); } @Override public IBinder onBind(Intent intent) { Log.i(TAG,"TimeService->onBind"); return null; } /** * 相关变量初始化 */ private void init(){ timer = new Timer(); sdf = new SimpleDateFormat("yyyy年MM月dd日 "+"hh:mm:ss"); timeIntent = new Intent(); bundle = new Bundle(); } /** * 发送广播,通知UI层时间已改变 */ private void sendTimeChangedBroadcast(){ bundle.putString("time", getTime()); timeIntent.putExtras(bundle); timeIntent.setAction(DynamicUIActivity.TIME_CHANGED_ACTION); //发送广播,通知UI层时间改变了 sendBroadcast(timeIntent); } /** * 获取最新系统时间 * @return */ private String getTime(){ return sdf.format(new Date()); } @Override public ComponentName startService(Intent service) { Log.i(TAG,"TimeService->startService"); return super.startService(service); } @Override public void onDestroy() { super.onDestroy(); Log.i(TAG,"TimeService->onDestroy"); } }
第四步:修改AndroidManifest.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zyg.demo.service.dynamicui" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".DynamicUIActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".UITimeReceiver"> <intent-filter> <action android:name="com.zyg.demo.service.dynamicui.action.TIME_CHANGED_ACTION"/> </intent-filter> </receiver> <service android:name=".TimeService"></service> </application> </manifest>
第五步:运行程序,效果如下:
相关文章推荐
- android客户端用bindservice来动态更新UI数据的实例
- android通过service实现更新并显示下载进度条,最后自动安装实例
- Android应用中通过AIDL机制实现进程间的通讯实例
- 【转】在Android中实现service动态更新UI界面
- 安卓开发观察者模式应用-一个service通知多个activity更新ui的实现
- android中实现service动态更新UI界面
- Android实例] Service和广播联合更新UI的例子
- Android应用中通过AIDL机制实现进程间的通讯实例
- android通过观察者模式实现更新UI
- Android应用中通过AIDL机制实现进程间的通讯实例
- Android service broadcast 动态 更新 UI 界面
- Android应用中通过AIDL机制实现进程间的通讯实例
- Android - TabHost 选项卡功能用法详解&&TabWidget切换卡的实现应用&&实例说明
- Android应用中通过AIDL机制实现进程间的通讯实例
- Android应用中通过AIDL机制实现进程间的通讯实例
- Android中service动态更新UI
- Android Service 通知Activity更新界面的方法研究|Service通过Broadcast更新UI
- (4.1.18.6)Android应用中通过AIDL机制实现进程间的通讯实例
- Android - TabHost 选项卡功能用法详解&&TabWidget切换卡的实现应用&&实例说明
- 有关Android中Service实现UI更新(Binder的运用)