【问题标题】:Android: Service stops when screen locks, why?Android:屏幕锁定时服务停止,为什么?
【发布时间】:2016-01-11 10:36:45
【问题描述】:

我使用一项服务,在该服务中我有一个计时器,它每分钟向我的 TCP/IP 服务器发送一条消息。

public void keepAlive() {
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try {
                    Gson gson = new Gson();
                    String message = gson.toJson(new StillAlive(Mode.STILLALIVE));
                    sendMessage(message);
                    Log.d("TCP-SEND", message);
                } catch(Exception e) {
                    Log.e("TCP1", e.getMessage());
                }
            }
        }, 60000, 60000);
    }

但是当我的手机锁定时。或者我按下按钮关闭显示,我的服务停止发送这些消息。

我不确定的是,如果服务停止,关闭显示器时,或者只是由于任何我不知道的原因而停止计时器。

有谁知道计时器在这种情况下是否停止?还是服务停止?

不胜感激! :-)

【问题讨论】:

  • 关闭电源以节省电池电量的是 wifi/移动数据。在移动设备上,消耗电池的不是数据量,而是天线通电的时间。如果您确实需要每分钟从服务器检查一次,请改用 Google Cloud Messaging。 Google Cloud Messaging 不会增加电池使用量,但如果您使用您的技术,假设您让它工作,至少会消耗总电池寿命的 20%(即使没有检测到任何变化)。对大多数人来说,20% 是很多,尤其是对于一个应用程序而言。请使用谷歌云消息
  • @StephanBranczyk:我的问题是,我需要发送这些消息来告诉我的 TCP 服务器,连接仍然正常。如果可行的话,我也可以每 5 分钟或类似的时间发送一次。但我需要在已知的时间范围内发送消息。这可能吗?
  • @StephanBranczyk 我想知道 whatsapp/telegram 等是如何处理这个问题的。他们在使用谷歌云消息吗?
  • whatsapp 的常见问题解答似乎暗示他们正在使用 GCM。请参阅whatsapp.com/faq/en/android/20887936“如果上述所有步骤都不起作用,则可能是您没有收到来自 Google 推送通知服务的更新,或者您的 Wi-Fi 或移动数据设置配置错误。”
  • Telegram 似乎同时使用 GCM 及其自定义解决方案(以防 GCM 不起作用)。 telegram.org/faq “我们目前在 Android 上有两种类型的通知:GCM 和我们自己的独立于 Google 的自定义通知服务。请注意,Google 通知 (GCM) 在某些 Android 设备上无法正常工作。Telegram 通知服务是可靠,但需要额外的电池资源。不过,它不会也不应该花费太多,所以请立即报告所有严重的电池耗尽情况。”

标签: android timer android-service


【解决方案1】:

这是因为您的设备开始休眠。强烈建议对此类进程使用其他实现:AlarmManager

看起来像这样(这是我的代码的一部分):

private static AlarmManager am;

//....
@SuppressLint("NewApi")
public static void startByAlarm(Context ctx, boolean wakeup, long nexttime, boolean autoStart)
    {
PendingIntent pi = wakeup? PendingIntent.getBroadcast(ctx, _.intentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT):
            PendingIntent.getService(ctx, _.intentalarm, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= android.os.Build.VERSION_CODES.KITKAT){
        am.setExact(wakeup?AlarmManager.RTC_WAKEUP:AlarmManager.RTC, nexttime, pi);
    } else{
        am.set(wakeup?AlarmManager.RTC_WAKEUP:AlarmManager.RTC, nexttime, pi);
    }
//or am.setRepeating ...
}

【讨论】:

  • 感谢您的快速回答:所以这意味着这是一个计时器问题? :-)
  • @progNewbie,我发现很多手机在长期使用过程中都有不同的行为。是的,你可以说,这是一个计时器问题。但核心问题是“电池寿命消耗”。如果您想以 100% 的概率 ping 您的服务器,您必须使用警报管理器。此外,我不知道您的代码使用 timer.stop() 是否是您代码的某些部分:)
【解决方案2】:

查看This answer by jscharf,这可能对您有所帮助,但您必须对此保持警惕,因为这是一项耗电的任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-03
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多