【问题标题】:Using Intent Service in combination with Alarm Manager结合使用意图服务和警报管理器
【发布时间】:2013-09-04 13:42:21
【问题描述】:

我使用了警报管理器来允许用户安排特定任务在特定时间重复。在应用程序的上下文中,我有一个 Android 游戏,人们可以在其中安排何时发送他们的船。警报管理器工作正常,警报在正确的时间启动等等。

当警报响起时(通常每隔一小时),我的 IntentService 将开始与服务器通信以发送船只。此操作可能需要 1 分钟,但最长可能持续 10 分钟。即使这一切都很好。警报被触发,船只被发送,每个人都很高兴。问题出现在晚上,我去睡觉,醒来时期待我的船已经被派了一夜。没有。日志和通知显示警报已正确触发,但 IntentService 在与服务器通信时似乎已被终止。

造成这种情况的可能原因是我没有像我醒着时那样每隔一段时间就看一次游戏,因此会保持某种形式的进程运行,这会阻止 IntentService免于被垃圾收集。

我已经尝试了很多方法来解决这个问题。我曾经使用 BroadCastReceiver,我曾经在 IntentService 中生成 ASyncTasks,但后来我重构了我的代码,不再使用这些东西,因为它们很糟糕服务实践。

我还检查了此资源:http://techtej.blogspot.com.es/2011/03/android-thread-constructspart-4.html,但我仍然不确定我正在做的事情是否正确处理这种情况。我已经为第二天晚上放置了一些广泛的日志记录,以便在早上进行审查,但我希望你们对此发表意见。

哦,我还请求在 onHandleIntent 函数的整个持续时间内使用 WakeLock:

PowerManager pm = (PowerManager) c.getSystemService(Context.POWER_SERVICE);                                         
this.wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "MyApplicationWakeLock");

我的 IntentService:

public class ScheduledRequestService extends IntentService {

    public ScheduledRequestService() {
        super("ScheduledRequestService");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startID){
        Logger.d("OnStartCommand!");
        return super.onStartCommand(intent, flags, startID);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        ScheduledRequest request = (ScheduledRequest) intent.getExtras().getSerializable("request");
        // This function will start a lot of client <-> server communication
        request.onExecute(this, intent);
    }

    @Override
    public void onDestroy(){
        Logger.d("OnDestroy!");
        super.onDestroy();
    }
}

所以,我的问题是;我的结构正确吗?我应该使用普通的 Service 而不是 IntentService 吗?我的 IntentService 在处理 Intent 时可以收集垃圾吗(我想我读到这是可能的)?

【问题讨论】:

    标签: java android android-service


    【解决方案1】:

    我的 IntentService 在处理 Intent 时是否可以收集垃圾(我想我读到这是可能的)?

    否,但您的进程可以终止。

    我的结构正确吗?

    如果您尝试使用_WAKEUP 警报,则不会。在这种情况下,您需要更仔细地进行设置,我建议使用WakefulBroadcastReceivermy WakefulIntentService 来处理这种模式。

    我应该使用普通服务而不是 IntentService 吗?

    不,IntentService 就可以了。您可能需要考虑使用startForeground() 使其成为前台服务。

    【讨论】:

    • 如果我的 IntentService 在处理 Intent 时无法被垃圾回收,那么它一定是阻止 Intent 正确完成所有工作的其他原因。 “_WAKEUP”警报是什么意思?我将尝试使其成为前台服务,看看它会做什么。感谢您的建议。
    • @Wotuu:正如我所写,您的进程可能正在终止。
    • 一切都可能被杀死,除了正在运行的服务,如果进程被终止,我的服务将因此被终止,那么我需要以某种方式防止这种情况发生。
    • @Wotuu:你不能“以某种方式防止这种情况”。你并不比用户更重要,用户可以随时以各种方式终止你的进程。不过,使用前台服务将降低操作系统自行终止您的进程的可能性。权衡是您的应用程序将在前台显示Notification,而Notification 应该引导用户返回用户界面,用户可以在其中执行某些操作来阻止您的应用程序在后台运行.
    • 我意识到用户可以手动杀死我的应用等,但如果我的应用停止它当前提供的自动化服务,那是他的选择。我唯一要防止的是操作系统完全停止服务,从而完全阻止服务运行。
    【解决方案2】:

    原来错误出在 Android 的垃圾收集器以外的地方。我使用缓存最终导致我“用完船”,因为在发送时间,它从池中扣除了发送的船只数量。然而,当它们返回时,它们从未被添加回缓存中。白天我可能手动刷新缓存或强制 Android 通过使用我的手机清除它,否则不会导致问题出现(同样多)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多