在Android開發中,我們經常想知道是否自己的服務處於後臺運行中,因為在後臺運行的服務器優先級會降低,也就極有可能會被系統給回收掉,有什麼好辦法呢?Google推薦我們將服務運行到前臺,如何知道服務是否處於後臺運行呢?可以通過獲取堆棧信息中棧頂的Activity是否為本應用即可。
1。下面是關健部分代碼:
(記得加上權限:)
mPackageName為本應用包名,mActivityManager為Activity管理對象
mActivityManager = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
mPackageName = getPackageName();
public boolean isAppOnForeground() { List tasksInfo = mActivityManager.getRunningTasks(1); if (tasksInfo.size() > 0) { L.i("top Activity = " + tasksInfo.get(0).topActivity.getPackageName()); // 應用程序位於堆棧的頂層 if (mPackageName.equals(tasksInfo.get(0).topActivity .getPackageName())) { return true; } } return false; }
2。下面又會有一個新問題,我們什麼時候調用這個函數呢?有兩個辦法,一個是主動,一個是被動,
①.主動辦法:在服務中開啟一個線程,每隔一段時間調用一下這個函數即可。
②.被動辦法:自定義一個BaseActivity繼承Activity,然後在onPause函數中回調通知一下服務中的此函數,然後應用中的每個Activity都繼承BaseActivity,即可知道棧頂中是否還有本應用的Activity。
3.當我們知道棧頂中的Activity不是本應用的瞭,我們的服務也就相應的降低瞭優先級,也就說系統需要內存的時候,首先就會回收此服務消耗的內存。此時,我們隻需將服務設置為前臺運行即可:
①.設置為前臺:第一個參數是通知ID,第二個參數是Notification對象
startForeground(SERVICE_NOTIFICATION, n);
②.停止前臺服務可調用:true代表清除通知欄
stopForeground(true);
public void updateServiceNotification(String message) { if (!PreferenceUtils.getPrefBoolean(this, PreferenceConstants.FOREGROUND, true)) return; String title = PreferenceUtils.getPrefString(this, PreferenceConstants.ACCOUNT, ""); Notification n = new Notification(R.drawable.login_default_avatar, title, System.currentTimeMillis()); n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; Intent notificationIntent = new Intent(this, MainActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); n.contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); n.setLatestEventInfo(this, title, message, n.contentIntent); startForeground(SERVICE_NOTIFICATION, n); } // 判斷程序是否在後臺運行的任務,其實個人覺得這個辦法並不太好, Runnable monitorStatus = new Runnable() { public void run() { try { L.i("monitorStatus is running... " + mPackageName); mMainHandler.removeCallbacks(monitorStatus); // 如果在後臺運行並且連接上瞭 if (!isAppOnForeground()) { L.i("app run in background..."); // if (isAuthenticated())//不判斷是否連接上瞭。 updateServiceNotification(getString(R.string.run_bg_ticker)); return;// 服務已在前臺運行,可以停止重復執行此任務 } else { stopForeground(true); } mMainHandler.postDelayed(monitorStatus, 1000L); } catch (Exception e) { e.printStackTrace(); L.i("monitorStatus:"+e.getMessage()); } } };
OK,以上僅是本人的一點心得體會,可能有不正確的地方,請大傢甄別使用,謝謝!