歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android應用實例之計時器之通過Service&BroadcastReceiver實現UI動態更新

實現的功能:計時器。

實現的思路: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,代碼如下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:Android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent" android:background="#FFFFFF">  
  5.     <TextView android:id="@+id/tv" android:layout_width="wrap_content"  
  6.         android:layout_height="wrap_content" android:text="當前時間: " />  
  7.     <TextView android:id="@+id/time" android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_toRightOf="@id/tv" />  
  10. </RelativeLayout>  

DynamicUIActivity類代碼如下:

  1. package com.zyg.demo.service.dynamicui;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.BroadcastReceiver;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.content.IntentFilter;  
  8. import android.graphics.Color;  
  9. import android.os.Bundle;  
  10. import android.widget.TextView;  
  11.   
  12. public class DynamicUIActivity extends Activity {  
  13.     public static String TIME_CHANGED_ACTION = "com.zyg.demo.service.dynamicui.action.TIME_CHANGED_ACTION";  
  14.     public static TextView time = null;  
  15.     private Intent timeService = null;  
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.           
  21.         //初始化UI   
  22.         initUI();  
  23.         System.out.println("initUI");  
  24.           
  25.         //注冊廣播-方法1   
  26.         /* 
  27.          * 配置 
  28.          * <receiver android:name=".UITimeReceiver"> 
  29.             <intent-filter> 
  30.                 <action android:name="com.zyg.demo.service.dynamicui.action.TIME_CHANGED_ACTION"/> 
  31.             </intent-filter> 
  32.         </receiver> 
  33.          */  
  34.           
  35.         //注冊廣播-方法2   
  36.         //注冊廣播,監聽後台Service發送過來的廣播   
  37.         //registerBroadcastReceiver();   
  38.           
  39.         //啟動服務,時間改變後發送廣播,通知UI層修改時間   
  40.         startTimeService();  
  41.     }  
  42.       
  43.     public TextView getTimeTextView(){  
  44.         return time;  
  45.     }  
  46.       
  47.     /** 
  48.      * 初始化UI 
  49.      */  
  50.     private void initUI(){  
  51.         time = (TextView)findViewById(R.id.time);  
  52.         time.setTextColor(Color.RED);  
  53.         time.setTextSize(15);  
  54.     }  
  55.       
  56.     /** 
  57.      * 注冊廣播 
  58.      */  
  59.     private void registerBroadcastReceiver(){  
  60.         UITimeReceiver receiver = new UITimeReceiver();  
  61.         IntentFilter filter = new IntentFilter(TIME_CHANGED_ACTION);  
  62.         registerReceiver(receiver, filter);  
  63.     }  
  64.       
  65.     /** 
  66.      * 啟動服務 
  67.      */  
  68.     private void startTimeService(){  
  69.         timeService = new Intent(this,TimeService.class);  
  70.         this.startService(timeService);  
  71.     }  
  72.       
  73.     @Override  
  74.     protected void onDestroy() {  
  75.         super.onDestroy();  
  76.         //停止服務   
  77.         stopService(timeService);  
  78.     }  
  79. }  

第二步:實現自定義BroadcatReceiver類UITimeReceiver,負責接收從後台Service發送過來的廣播,獲取最新時間數據後更新UI層組件。本類最好作為UI層(Activity)的內部類,此處將其作為外部類實現(通過xml文件配置注冊BroadcatReceiver,如果是內部類如何通過xml文件配置目前沒找到),有意顯示如此做導致代碼不夠優雅。

UITimeReceiver代碼如下:

  1. package com.zyg.demo.service.dynamicui;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.os.Bundle;  
  7.   
  8. /** 
  9.  * 自定義的UI層BroadcastReceiver,負責監聽從後台Service發送過來的廣播,根據廣播數據更新UI 
  10.  * @author zhangyg 
  11.  */  
  12. public class UITimeReceiver extends BroadcastReceiver{  
  13.     private DynamicUIActivity dUIActivity = new DynamicUIActivity();  
  14.     @Override  
  15.     public void onReceive(Context context, Intent intent) {  
  16.         String action = intent.getAction();  
  17.         if(DynamicUIActivity.TIME_CHANGED_ACTION.equals(action)){  
  18.             Bundle bundle = intent.getExtras();  
  19.             String strtime = bundle.getString("time");  
  20.             //此處實現不夠優雅,為了在UITimeReceiver中使用DynamicUIActivity中的TextView組件time,而將其設置為public類型,   
  21.             //更好的實現是將UITimeReceiver作為DynamicUIActivity的內部類   
  22.             dUIActivity.time.setText(strtime);  
  23.         }  
  24.     }  
  25. }  

第三步:實現自定義Service類TimeService,其代碼如下:

  1. package com.zyg.demo.service.dynamicui;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5. import java.util.Timer;  
  6. import java.util.TimerTask;  
  7.   
  8. import android.app.Service;  
  9. import android.content.ComponentName;  
  10. import android.content.Intent;  
  11. import android.os.Bundle;  
  12. import android.os.IBinder;  
  13. import android.util.Log;  
  14.   
  15. public class TimeService extends Service{  
  16.     private String TAG = "TimeService";  
  17.     private Timer timer = null;  
  18.     private SimpleDateFormat sdf = null;  
  19.     private Intent timeIntent = null;  
  20.     private Bundle bundle = null;  
  21.     @Override  
  22.     public void onCreate() {  
  23.         super.onCreate();  
  24.         Log.i(TAG,"TimeService->onCreate");  
  25.         //初始化   
  26.         this.init();  
  27.         //定時器發送廣播   
  28.         timer.schedule(new TimerTask() {  
  29.             @Override  
  30.             public void run() {  
  31.                 //發送廣播   
  32.                 sendTimeChangedBroadcast();  
  33.             }  
  34.         }, 1000,1000);  
  35.     }  
  36.       
  37.     @Override  
  38.     public IBinder onBind(Intent intent) {  
  39.         Log.i(TAG,"TimeService->onBind");  
  40.         return null;  
  41.     }  
  42.       
  43.     /** 
  44.      * 相關變量初始化 
  45.      */  
  46.     private void init(){  
  47.         timer = new Timer();  
  48.         sdf = new SimpleDateFormat("yyyy年MM月dd日 "+"hh:mm:ss");  
  49.         timeIntent = new Intent();  
  50.         bundle = new Bundle();  
  51.     }  
  52.       
  53.     /** 
  54.      * 發送廣播,通知UI層時間已改變 
  55.      */  
  56.     private void sendTimeChangedBroadcast(){  
  57.         bundle.putString("time", getTime());  
  58.         timeIntent.putExtras(bundle);  
  59.         timeIntent.setAction(DynamicUIActivity.TIME_CHANGED_ACTION);  
  60.         //發送廣播,通知UI層時間改變了   
  61.         sendBroadcast(timeIntent);  
  62.     }  
  63.       
  64.     /** 
  65.      * 獲取最新系統時間 
  66.      * @return 
  67.      */  
  68.     private String getTime(){  
  69.         return sdf.format(new Date());  
  70.     }  
  71.       
  72.     @Override  
  73.     public ComponentName startService(Intent service) {  
  74.         Log.i(TAG,"TimeService->startService");  
  75.         return super.startService(service);  
  76.     }  
  77.       
  78.     @Override  
  79.     public void onDestroy() {  
  80.         super.onDestroy();  
  81.         Log.i(TAG,"TimeService->onDestroy");  
  82.     }  
  83. }  

第四步:修改AndroidManifest.xml文件,代碼如下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.zyg.demo.service.dynamicui"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="8" />  
  7.   
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  9.         <activity android:name=".DynamicUIActivity"  
  10.                   android:label="@string/app_name">  
  11.             <intent-filter>  
  12.                 <action android:name="android.intent.action.MAIN" />  
  13.                 <category android:name="android.intent.category.LAUNCHER" />  
  14.             </intent-filter>  
  15.         </activity>  
  16.         <receiver android:name=".UITimeReceiver">  
  17.             <intent-filter>  
  18.                 <action android:name="com.zyg.demo.service.dynamicui.action.TIME_CHANGED_ACTION"/>  
  19.             </intent-filter>  
  20.         </receiver>  
  21.         <service android:name=".TimeService"></service>  
  22.     </application>  
  23. </manifest>  

第五步:運行程序,效果如下:

Copyright © Linux教程網 All Rights Reserved