Android之后臺服務判斷本應用Activity是否處于棧頂

jopen 10年前發布 | 81K 次閱讀 Android Android開發 移動開發

在Android開發中,我 們經常想知道是否自己的服務處于后臺運行中,因為在后臺運行的服務器優先級會降低,也就極有可能會被系統給回收掉,有什么好辦法呢?Google推薦我們 將服務運行到前臺,如何知道服務是否處于后臺運行呢?可以通過獲取堆棧信息中棧頂的Activity是否為本應用即可。

1。下面是關健部分代碼:

(記得加上權限:<uses-permissionandroid:name="android.permission.GET_TASKS"/>)

mPackageName為本應用包名,mActivityManager為Activity管理對象

mActivityManager = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));

mPackageName = getPackageName();

    public boolean isAppOnForeground() {
List<RunningTaskInfo> 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;  
}  </pre><a href="/misc/goto?guid=4959551346025940137" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div>
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());  
        }  
    }  
};  </pre><a href="/misc/goto?guid=4959551346025940137" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div> 來自:http://blog.csdn.net/way_ping_li/article/details/17253943

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!