【问题标题】:Correct way to do polling in Android app在 Android 应用中进行轮询的正确方法
【发布时间】:2016-10-13 21:41:28
【问题描述】:

我必须开发一个简单的应用程序,每 5 秒从服务器获取一个 json。我知道这会耗尽电池电量,但由于我无法控制服务器,这是我目前唯一的解决方案,所以请和我在一起。 (这是一个演示应用,最终版本会完全不同)

我做了什么:

我创建了一个 IntentService 并在他的 onHandleIntent 中执行 http 请求并异步管理响应。阅读文档,IntentService 优于服务。最后,如其他主题中所见,我使用 AlarmManager 类重新创建 intentService。方法是这样的:

private void repeat() {
    lastTrigger = System.currentTimeMillis();
    alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    Intent serviceIntent = new Intent(this, StatusPollingService.class);
    PendingIntent pendingIntent = PendingIntent.getService(this, 0, serviceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP, lastTrigger + UPDATE_INTERVAL, pendingIntent);
}

在我的第一个 Activity 中的 onCreate 中,我只需启动服务:

    serviceIntent = new Intent(BaseActivity.this, StatusPollingService.class);
    startService(serviceIntent);

我的问题:

  1. 当我关闭应用程序(使用后退按钮)时,intentService 会继续执行请求并重新创建自身(如预期的那样),因此我必须手动终止它
  2. 我想在我的应用每次进入后台时停止轮询,并在进入前台时重新启动,以限制电池消耗

我的其他问题:

我实现了一个类,当应用程序进入后台/前台时触发侦听器。我在 BaseActivity 和 IntentService 中实现了接口。当应用程序进入后台时,布尔值变为 false,我不执行 repeat() 方法。当我进入前台时,在我的方法 onBecameForeground 中我只是创建了服务:

    serviceIntent = new Intent(BaseActivity.this, StatusPollingService.class);
@Override
public void onBecameForeground() {
    startService(serviceIntent);
}

进入后台没有问题,但是进入前台会创建多个intentService,我在那一刻拥有的每个Activity都有一个intentService(我在日志中看到了)。

我的问题:

  1. 这是完成这项工作的最佳方式吗?我该如何解决这些问题?
  2. 如果这是最好的(或不太糟糕的)方法,我该如何创建 IntentService 的单个实例?

非常感谢您的帮助

【问题讨论】:

    标签: android polling intentservice


    【解决方案1】:

    如果您只需要在前台使用它,那么我不会打扰警报。只需每 5 秒使用 Handler 将意图发布到您的意图服务。

    假设应该只有一个意图服务实例,因此如果您发布多个意图进行处理,它们将排队,并且将在您的意图服务中为每个意图调用handleIntent。但是请注意,如果您的服务处理意图的速度足够快,那么它可能会在您发布另一个意图之前完成(并销毁) - 因此您将看到正在创建的服务的多个实例。但一次只会有一个实例。

    编辑:扩展一点,当(如果)您将在后台轮询服务器时,您将需要警报,所以不要通过该代码;)处理程序将在后台保持“冻结”为操作系统不计算设备为 Handler 延迟执行而休眠的时间。

    【讨论】:

    • 是的,我正在寻找带有 Handler 和 Timers 的解决方案,但我应该在哪里使用它?在我的应用程序类中?
    • 主要活动也可以(再次假设您只需要它在前台工作),除非您有多个不断切换的活动。然后一些更永久的东西 - 是的,Application 类 - 应该更好。
    • 无论如何我知道一次应该有一个实例,但我这样做:我尝试连接到一个无法访问的 url,超时时间为 1 秒。当我导航到我的应用程序,回家然后返回时,我有多个日志显示“正在连接到xx”,然后有多个日志显示“无法连接”。我在同步和异步请求中得到相同的结果,我无法解释这一点
    • 所以所有“连接”都先于所有“无法连接”?嗯,尝试打印出服务的onCreate、onDestroy和handleIntent中的一些日志。也许还打印服务的哈希码以查看它是否是同一个实例。顺便说一句,同步与异步请求在这里无关紧要,因为 IntentService 无论如何都会在后台线程上执行意图。
    猜你喜欢
    • 1970-01-01
    • 2013-04-27
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2013-02-20
    • 2011-03-20
    相关资源
    最近更新 更多