WakefulIntentService实施澄清WakefulIntentService

2023-09-04 12:29:42 作者:咱繼續、任性

Commonsware的 WakefulIntentService 精美的作品,但也有一些事情,我不完全得到。下面是服务的核心 - 的来源:

 类WIS扩展IntentService {

    私有静态最后字符串名称= WIS.class.getName()+.Lock;
    私有静态挥发WakeLock lockStatic = NULL;

    同步私有静态PowerManager.WakeLock GETLOCK(上下文的背景下){
        如果(lockStatic == NULL){
            PowerManager的经理=(电源管理器)上下文
                    .getSystemService(Context.POWER_SERVICE);
            lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,名);
            lockStatic.setReferenceCounted(真正的);
        }
        返回(lockStatic);
    }

    公共静态无效startWIS(上下文ctxt,意图我){
        GETLOCK(ctxt.getApplicationContext())获得()。
        ctxt.startService(ⅰ);
    }

    公共WIS(字符串名称){
        超(名称);
        setIntentRedelivery(真正的);
    }

    @覆盖
    公众诠释onStartCommand(意向意图,诠释标志,诠释startId){
        PowerManager.WakeLock锁= GETLOCK(this.getApplicationContext());
        如果(lock.isHeld()||(标志&安培;!START_FLAG_REDELIVERY)= 0){//?
            lock.acquire();
        }
        super.onStartCommand(意向,标志,startId);
        返程(START_REDELIVER_INTENT);
    }

    @覆盖
    保护无效onHandleIntent(意向意图){
        尝试 {
            //做你的事
        } 最后 {
            PowerManager.WakeLock锁= GETLOCK(this.getApplicationContext());
            如果(lock.isHeld())lock.release();
        }
    }
}
 

问题

如果进程被杀死刚发生后的的onReceive()我们的报警接收机的回报?也就是说,如果服务的onCreate()(如果该服务尚未实例化)或者 onStartCommand()永远不会运行。 AFAIK杀死一个过程需要它的锁吧。或者,这是一个不可能的情况? 在考虑到previous应(标志和安培; START_FLAG_RETRY)?添加 为什么如果(!lock.isHeld())检查? 为什么 this.getApplicationContext()需要的?是不是就够了吗? 解决方案   

AFAIK杀死一个过程需要它的锁吧。

正确的。

  

或者,这是一个不可能的情况?

这是相当不可能的,但绝对不是不可能的。

  

在考虑到previous应(标志和安培; START_FLAG_RETRY)?加入

国家食品药品监管局就新修订的 药品注册管理办法 召开发布会

这应该由 START_FLAG_REDELIVERY 被覆盖。 AFAIK,与 START_REDELIVER_INTENT ,没有重试没有开航 。如果你有证据,相反,我很乐意看到它。

  

为什么,如果(!lock.isHeld())检查?

调用发布() WakeLock 未举行将导致异常。这仅仅是一个安全毯,以确保我们不拉闸引发不必要的异常。从理论上讲,它不应该被需要;从理论上讲,我应该有头发。

  

为什么this.getApplicationContext()需要的?是不是这样就够了吗?

我们创建一个 WakeLock ,这是我们在一个静态数据成员持有。的也许的的 getSystemService()调用不拉闸把上下文里面把它称为在电源管理器。而且,即使它,的也许的的上下文将不会被传递到生成的 WakeLock 实例。不过,为了安全起见,使用 getApplicationContext(),我们得到了 WakeLock 的方式,确保只有上下文那么我们就可能泄漏是单应用程序上下文,它作为一个单身,实际上是pre-泄露。 : - )

Commonsware's WakefulIntentService works beautifully but there are some things I do not quite get. Below is the core of the service - a stripped down version of the source :

class WIS extends IntentService {

    private static final String NAME = WIS.class.getName() + ".Lock";
    private static volatile WakeLock lockStatic = null;

    synchronized private static PowerManager.WakeLock getLock(Context context) {
        if (lockStatic == null) {
            PowerManager mgr = (PowerManager) context
                    .getSystemService(Context.POWER_SERVICE);
            lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NAME);
            lockStatic.setReferenceCounted(true);
        }
        return (lockStatic);
    }

    public static void startWIS(Context ctxt, Intent i) {
        getLock(ctxt.getApplicationContext()).acquire();
        ctxt.startService(i);
    }

    public WIS(String name) {
        super(name);
        setIntentRedelivery(true);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
        if (!lock.isHeld() || (flags & START_FLAG_REDELIVERY) != 0) { // ?
            lock.acquire();
        }
        super.onStartCommand(intent, flags, startId);
        return (START_REDELIVER_INTENT);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            // do your thing
        } finally {
            PowerManager.WakeLock lock = getLock(this.getApplicationContext());
            if (lock.isHeld()) lock.release();
        }
    }
}

Questions

What happens if the process is killed just after the onReceive() of our alarm receiver returns ? That is if service onCreate() (if the service is not already instantiated) or onStartCommand() never run. AFAIK a process killed takes its locks with it. Or is this an impossible scenario ? In view of the previous should (flags & START_FLAG_RETRY) be added ? Why the if (!lock.isHeld()) check ? Why is this.getApplicationContext() needed ? is not this enough ?

解决方案

AFAIK a process killed takes its locks with it.

Correct.

Or is this an impossible scenario ?

It's fairly unlikely, but certainly not impossible.

In view of the previous should (flags & START_FLAG_RETRY) be added ?

That should be covered by START_FLAG_REDELIVERY. AFAIK, with START_REDELIVER_INTENT, there is no RETRY without REDELIVERY. If you have evidence to the contrary, I'd love to see it.

Why the if (!lock.isHeld()) check ?

Calling release() on a WakeLock that is not held results in an exception. This is just a safety blanket to ensure we don't wind up throwing an unnecessary exception. In theory, it should never be needed; in theory, I should have hair.

Why is this.getApplicationContext() needed ? is not this enough ?

We create a WakeLock, which we hold in a static data member. Probably the getSystemService() call does not wind up putting the Context that called it inside the PowerManager. And, even if it did, probably the Context would not be passed to the resulting WakeLock instance. However, to be safe, by using getApplicationContext(), we obtain the WakeLock in a fashion that ensures that the only Context we could possibly "leak" is the singleton application context, which, as a singleton, is effectively pre-leaked. :-)

相关推荐
 
精彩推荐
图片推荐