提高Service优先级,避免被系统回收

本文介绍了一种通过创建一个不被清除的Notification来确保Android Service持续运行的方法,即使在内存紧张的情况下也能避免被系统终止。文章详细展示了如何利用startForeground()函数,并提供了兼容旧版API的实现方式。
设置一个不会被清除的Notification就能实现Service不会被系统回收,也不会被一般的第三方内存管理工具给清除掉;如果你不想显示一个Notification的话,可以这么做:
Notification noti = new Notification();
startForeground(YOUR_NOTIFICATION_ID, noti);
public final void  startForeground   (int id, Notification notification)
Parameters
idThe identifier for this notification as per NotificationManager.notify(int, Notification).
notificationThe Notification to be displayed.

Make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. By default services are background, meaning that if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You can set this flag if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.

If you need your application to run on platform versions prior to API level 5, you can use the following model to call the the older setForeground() or this modern method as appropriate:

private static final Class<?>[] mSetForegroundSignature = new Class[] {
    boolean.class};
private static final Class<?>[] mStartForegroundSignature = new Class[] {
    int.class, Notification.class};
private static final Class<?>[] mStopForegroundSignature = new Class[] {
    boolean.class};

private NotificationManager mNM;
private Method mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];

void invokeMethod(Method method, Object[] args) {
    try {
        method.invoke(this, args);
    } catch (InvocationTargetException e) {
        // Should not happen.
        Log.w("ApiDemos", "Unable to invoke method", e);
    } catch (IllegalAccessException e) {
        // Should not happen.
        Log.w("ApiDemos", "Unable to invoke method", e);
    }
}

/**
 * This is a wrapper around the new startForeground method, using the older
 * APIs if it is not available.
 */
void startForegroundCompat(int id, Notification notification) {
    // If we have the new startForeground API, then use it.
    if (mStartForeground != null) {
        mStartForegroundArgs[0] = Integer.valueOf(id);
        mStartForegroundArgs[1] = notification;
        invokeMethod(mStartForeground, mStartForegroundArgs);
        return;
    }

    // Fall back on the old API.
    mSetForegroundArgs[0] = Boolean.TRUE;
    invokeMethod(mSetForeground, mSetForegroundArgs);
    mNM.notify(id, notification);
}

/**
 * This is a wrapper around the new stopForeground method, using the older
 * APIs if it is not available.
 */
void stopForegroundCompat(int id) {
    // If we have the new stopForeground API, then use it.
    if (mStopForeground != null) {
        mStopForegroundArgs[0] = Boolean.TRUE;
        invokeMethod(mStopForeground, mStopForegroundArgs);
        return;
    }

    // Fall back on the old API.  Note to cancel BEFORE changing the
    // foreground state, since we could be killed at that point.
    mNM.cancel(id);
    mSetForegroundArgs[0] = Boolean.FALSE;
    invokeMethod(mSetForeground, mSetForegroundArgs);
}

@Override
public void onCreate() {
    mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    try {
        mStartForeground = getClass().getMethod("startForeground",
                mStartForegroundSignature);
        mStopForeground = getClass().getMethod("stopForeground",
                mStopForegroundSignature);
        return;
    } catch (NoSuchMethodException e) {
        // Running on an older platform.
        mStartForeground = mStopForeground = null;
    }
    try {
        mSetForeground = getClass().getMethod("setForeground",
                mSetForegroundSignature);
    } catch (NoSuchMethodException e) {
        throw new IllegalStateException(
                "OS doesn't have Service.startForeground OR Service.setForeground!");
    }
}

@Override
public void onDestroy() {
    // Make sure our notification is gone.
    stopForegroundCompat(R.string.foreground_service_started);
}




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值