首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果持有Android操作系统的应用程序或服务被杀死,Android操作系统会发布唤醒吗?

如果持有Android操作系统的应用程序或服务被杀死,Android操作系统会发布唤醒吗?
EN

Stack Overflow用户
提问于 2011-01-15 03:51:09
回答 2查看 12.9K关注 0票数 48

我有关于觉醒的问题。在下面所示的情况下,android是否会发布唤醒锁(如果需要指定的话)以防止锁锁被保留,并在关闭电源(而不是睡眠)之前浪费电池。

案例1-a:

App已经在它的一个线程中获得了唤醒(w/o超时选项)(请认为在这种情况下它是合理的),它的设计是为了在关键任务完成时释放唤醒。应用程序可以被任务管理器或臭名昭著的任务杀手杀死,而应用程序没有机会让它的线程释放唤醒。那辆警车呢?

判例1-b:

(如果对案例1-a的回答是“是的,别担心”,那么请忽略这个案例。)与案例1一样-a,但应用程序给出超时选项唤醒,比如说3秒。此超时选项有效吗?

案例2-a:

请想象一下,有一个服务是由AlarmManager (通过广播接收器)启动的,并且该服务已经获得了一个觉醒(w/o超时选项)。这项服务的目的是使唤醒时间最短。但不幸的是,由于内存紧张,Android选择了这个服务。(我不知道当买了wakelock的时候OS是否会杀死服务,但我想OS并不在意。但我希望OS稍后会发布wakelock。)那辆警车呢?

案例2-b:

(如果对案例2-a的回答是“是的,别担心”,那么请忽略这个案例。)与案例2-a相同,但是服务给了唤醒的超时选项,比如3秒。此超时选项有效吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-28 01:28:29

WakeLock实现概述

当我们使用pm.newWakeLock创建一个新的觉醒时,PowerManager只是创建一个新的wakelock对象并返回。WakeLock对象不是绑定对象,因此不能通过多个进程使用它。但是,在这个WakeLock对象中,它包含一个名为mToken的绑定对象。

代码语言:javascript
复制
    WakeLock(int flags, String tag) {
        mFlags = flags;
        mTag = tag;
        mToken = new Binder();
    }

因此,当您对这个WakeLock对象调用、获取或发布时,它实际上将该令牌传递给PowerManagerService

代码语言:javascript
复制
    private void acquireLocked() {
        if (!mRefCounted || mCount++ == 0) {
            mHandler.removeCallbacks(mReleaser);
            try {
                mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
            } catch (RemoteException e) {
            }
            mHeld = true;
        }
    }

看看PowerManagerService在获取或释放唤醒锁时是如何工作的,这将帮助您回答您的问题。

代码语言:javascript
复制
void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
        int uid, int pid) {
    synchronized (mLock) {
        ...
        WakeLock wakeLock;
        int index = findWakeLockIndexLocked(lock);
        if (index >= 0) {
            ...
            // Update existing wake lock.  This shouldn't happen but is harmless.
            ...
        } else {
            wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
            try {
                lock.linkToDeath(wakeLock, 0);
            } catch (RemoteException ex) {
                throw new IllegalArgumentException("Wake lock is already dead.");
            }
            notifyWakeLockAcquiredLocked(wakeLock);
            mWakeLocks.add(wakeLock);
        }
        ...
    }
    ...
}

关键语句是lock.linkToDeath(wakeLock, 0);lock正是我们之前提到的mToken。如果绑定器消失,此方法将为通知注册收件人( wakeLock)。如果这个绑定器对象意外地消失了(通常是因为它的宿主进程被终止了),那么binderDied方法将在接收者上被调用。

注意,PowerManagerService中的PowerManagerServicePowerManager中的WakeLock不同,它是IBinder.DeathRecipient的实现。因此,请查看它的binderDied方法。

代码语言:javascript
复制
    @Override
    public void binderDied() {
        PowerManagerService.this.handleWakeLockDeath(this);
    }

handleWakeLockDeath将发布这个唤醒锁。

代码语言:javascript
复制
private void handleWakeLockDeath(WakeLock wakeLock) {
    synchronized (mLock) {
        ...
        int index = mWakeLocks.indexOf(wakeLock);
        if (index < 0) {
            return;
        }

        mWakeLocks.remove(index);
        notifyWakeLockReleasedLocked(wakeLock);

        applyWakeLockFlagsOnReleaseLocked(wakeLock);
        mDirty |= DIRTY_WAKE_LOCKS;
        updatePowerStateLocked();
    }
}

所以我认为在你的问题中,在这两种情况下,答案都是不用担心。至少在Android4.2(代码来源)中,这是正确的。此外,WakeLock类在PowerManager中有一个finalize方法,但这不是问题的关键。

票数 49
EN

Stack Overflow用户

发布于 2011-04-05 07:54:26

我假设(我不确定这一点) Android系统不会为被杀死的进程保持清醒。最有可能的情况是,当它用sigkill杀死一个进程时,它也会删除该进程所持有的所有唤醒。

否则,就像你说的,撞车会导致电话始终保持清醒,这一点我还没有观察到。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4697873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档