Android AlarmManager實現不間斷輪詢服務
在訊息的獲取上是選擇輪詢還是推送得根據實際的業務需要來技術選型,例如對訊息實時性比較高的需求,比如微博新通知或新聞等那就最好是用推送了。但如果只是一般的訊息檢測比如更新檢查,可能是半個小時或一個小時一次,那用輪詢也是一個不錯的選擇,因為不需要額外搭建推送伺服器,不用額外配置推送服務。另外推送現在一般以維持長連線的方式實現,在手機客戶端也會耗費一定的電量。今天就介紹一個在Android上實現輪詢機制的方法——使用AlarmManager
AlarmManager在Android中主要用來定時處理一個事件或是定期處理一個事件,比如鬧鐘應用就是使用AlarmManager來實現的,我們今天要使用AlarmManager的定期執行功能來實現輪詢的功能。對於定期執行任務也可以用Timer和TimerTask來實現,也可以開一個Service在Thread裡面以while迴圈來實現。但最好的方案還是選用AlarmManager,這裡涉及一個Android系統鎖的機制,即系統在檢測到一段時間沒有活躍以後,會關閉一些不必要的服務來減少資源和電量消耗。使用Timer和Service來實現的話很可能出現的情況就是螢幕熄滅後一段時間,服務就被停止了,當然輪詢也就被停止了。這個大家可以實驗一下,之前我寫過一篇文章也介紹了一種保持後臺喚醒的機制《使用WakeLock使Android應用程式保持後臺喚醒》,感興趣的可以看看。那麼接下來就開始使用AlarmManager+Service+Thread來實現我們的輪詢服務吧!
一、新建輪詢工具類PollingUtils.java
- public class PollingUtils {
- //開啟輪詢服務
- public static void startPollingService(Context context, int seconds, Class<?> cls,String action) {
- //獲取AlarmManager系統服務
- AlarmManager manager = (AlarmManager) context
- .getSystemService(Context.ALARM_SERVICE);
- //包裝需要執行Service的Intent
- Intent intent = new Intent(context, cls);
- intent.setAction(action);
- PendingIntent pendingIntent = PendingIntent.getService(context, 0,
- intent, PendingIntent.FLAG_UPDATE_CURRENT);
- //觸發服務的起始時間
- long triggerAtTime = SystemClock.elapsedRealtime();
- //使用AlarmManger的setRepeating方法設定定期執行的時間間隔(seconds秒)和需要執行的Service
- manager.setRepeating(AlarmManager.ELAPSED_REALTIME, triggerAtTime,
- seconds * 1000, pendingIntent);
- }
- //停止輪詢服務
- public static void stopPollingService(Context context, Class<?> cls,String action) {
- AlarmManager manager = (AlarmManager) context
- .getSystemService(Context.ALARM_SERVICE);
- Intent intent = new Intent(context, cls);
- intent.setAction(action);
- PendingIntent pendingIntent = PendingIntent.getService(context, 0,
- intent, PendingIntent.FLAG_UPDATE_CURRENT);
- //取消正在執行的服務
- manager.cancel(pendingIntent);
- }
- }
二、構建輪詢任務執行PollingService.java
- public class PollingService extends Service {
- public static final String ACTION = "com.ryantang.service.PollingService";
- private Notification mNotification;
- private NotificationManager mManager;
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- initNotifiManager();
- }
- @Override
- public void onStart(Intent intent, int startId) {
- new PollingThread().start();
- }
- //初始化通知欄配置
- private void initNotifiManager() {
- mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- int icon = R.drawable.ic_launcher;
- mNotification = new Notification();
- mNotification.icon = icon;
- mNotification.tickerText = "New Message";
- mNotification.defaults |= Notification.DEFAULT_SOUND;
- mNotification.flags = Notification.FLAG_AUTO_CANCEL;
- }
- //彈出Notification
- private void showNotification() {
- mNotification.when = System.currentTimeMillis();
- //Navigator to the new activity when click the notification title
- Intent i = new Intent(this, MessageActivity.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i,
- Intent.FLAG_ACTIVITY_NEW_TASK);
- mNotification.setLatestEventInfo(this,
- getResources().getString(R.string.app_name), "You have new message!", pendingIntent);
- mManager.notify(0, mNotification);
- }
- /**
- * Polling thread
- * 模擬向Server輪詢的非同步執行緒
- * @Author Ryan
- * @Create 2013-7-13 上午10:18:34
- */
- int count = 0;
- class PollingThread extends Thread {
- @Override
- public void run() {
- System.out.println("Polling...");
- count ++;
- //當計數能被5整除時彈出通知
- if (count % 5 == 0) {
- showNotification();
- System.out.println("New message!");
- }
- }
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- System.out.println("Service:onDestroy");
- }
- }
三、在MainActivity.java中開啟和停止PollingService
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //Start polling service
- System.out.println("Start polling service...");
- PollingUtils.startPollingService(this, 5, PollingService.class, PollingService.ACTION);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- //Stop polling service
- System.out.println("Stop polling service...");
- PollingUtils.stopPollingService(this, PollingService.class, PollingService.ACTION);
- }
- }
四、執行效果
執行工程後可以在控制檯輸出看到,每隔5s就發出一個通知,退出Activity時,輪詢服務就停止了,達到了我們事先期望的效果,並且鎖屏後很長一段時間也不會停止服務,因為AlarmManager是系統及服務。Demo效果如下圖:
在手機上我們可以看到彈出的通知資訊,點選通知則進到訊息介面:
當進入訊息詳情Activity時,頂部狀態列的訊息通知就會取消,使用如下方式也可以取消狀態列頂部的訊息通知顯示:
- NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
- manager.cancelAll();
以上就實現了使用AlarmManger實現輪詢的一種方式,有不足或缺陷的地方歡迎大家留言補充,以上程式碼只是部分,需要工程原始碼的同學可以到Github上Clone:https://github.com/tangren03/RTPollingDemo
加入我們的QQ群或微信公眾賬號請檢視:Ryan's
zone公眾賬號及QQ群
同時歡迎關注我的新浪微博和我交流:@唐韌_Ryan
相關文章
- 【TAF】使用Oracle RAC的TAF技術實現不間斷查詢Oracle
- ajax實現輪詢
- Android之AlarmManagerAndroid
- Android利用AlarmManager執行定時任務Android
- eureka實現服務之間的呼叫
- 使用輪詢&長輪詢實現網頁聊天室網頁
- 微服務~Eureka實現的服務註冊與發現及服務之間的呼叫微服務
- 簡單實現附近周邊服務查詢功能
- Java實現負載均衡演算法--輪詢和加權輪詢Java負載演算法
- 自己編寫平滑加權輪詢演算法,實現反向代理叢集服務的平滑分配演算法
- android學習筆記--AlarmManagerAndroid筆記
- linux實現DNS輪詢實現負載平衡LinuxDNS負載
- Android判斷服務是否在執行Android
- Android中的定時器AlarmManagerAndroid定時器
- Android實現Thrift服務端與客戶端Android服務端客戶端
- Go語言中時間輪的實現Go
- 層級時間輪的 Golang 實現Golang
- js實現的單行文字不間斷無縫滾動效果JS
- Docker實現服務發現Docker
- NodeJs服務註冊與服務發現實現NodeJS
- HarmonyOS 應用服務生態不斷壯大 原子化服務助力夥伴商業成功
- 終端斷開,任務不斷
- Android UI 實現廣告 Banner 輪播效果AndroidUI
- Android模組介面服務,暴露SDK+介面服務查詢(類似微信.api)AndroidAPI
- etcd實現服務發現
- 藉助 Turbolinks 實現不間斷的網頁音樂播放器網頁播放器
- 實現SSR服務端渲染服務端
- PHP實現代理服務功能PHP
- Laravel 服務容器實現原理Laravel
- CXF實現webService服務(一)Web
- 教你如何實現 Android TextView 文字輪播效果AndroidTextView
- Android自定義View實現文字輪播效果AndroidView
- 實現一個簡單的輪詢演算法演算法
- 前端效能最佳化:使用 Web Workers 實現輪詢前端Web
- [轉]geoServer 入門到實戰(安裝,釋出服務,wfs空間查詢)Server
- Zookeeper實現服務註冊/發現
- 服務發現-從原理到實現
- Js+CSS間斷和不間斷文字滾動程式碼JSCSS