Android 安卓:如何正确等待服务流程完成

Android 安卓:如何正确等待服务流程完成,android,background,notifications,updates,Android,Background,Notifications,Updates,下面是一个场景: 我有两项活动和一项服务 第一个活动是登录视图/搜索页面。第二个活动显示搜索结果 搜索始终针对内部SQLite数据库执行 需要定期(比如每天)从远程源更新db,这是一个漫长的过程 如果用户在更新期间执行搜索,我希望在显示“请等待”进度警报的同时等待更新结束。在刷新完成之前,我不想查询和显示搜索结果 数据库更新由AlarmManager触发,并由服务执行,该服务在更新过程中将“更新”状态放入数据库 我可以轻松地查询状态,但如何等待并定期重新查询数据库?我使用AsyncTask来处理

下面是一个场景:

  • 我有两项活动和一项服务
  • 第一个活动是登录视图/搜索页面。第二个活动显示搜索结果
  • 搜索始终针对内部SQLite数据库执行
  • 需要定期(比如每天)从远程源更新db,这是一个漫长的过程
  • 如果用户在更新期间执行搜索,我希望在显示“请等待”进度警报的同时等待更新结束。在刷新完成之前,我不想查询和显示搜索结果
  • 数据库更新由AlarmManager触发,并由服务执行,该服务在更新过程中将“更新”状态放入数据库
  • 我可以轻松地查询状态,但如何等待并定期重新查询数据库?我使用AsyncTask来处理搜索结果,我下意识的反应是在
    AsyncTask\doInBackground
    方法中加入wait()循环,但这很危险,根本不起作用,因为我没有控制UI线程,所以我最终得到了
    IllegalMonitorStateException
  • 在这种情况下,正确等待(甚至可能是状态更新)的“正确”方式是什么

    另外,我将“wait”代码放在一个Runnable中,并在开始异步任务之前执行它。它可以工作,例如
    Thread.sleep(2000)
    但我不确定这样做是否安全。有没有人有过
    FutureTask
    方面的经验

    如果用户在 更新我想等到更新 显示“请稍候”时已结束 进展警报。我不想质疑 并显示搜索结果,直到 刷新已完全完成

    这是你的决定,但请记住,你是在制造自己的问题。就我个人而言,我会放弃这个要求。用户不应该因为闹钟响而感到不便

    例如,您可以禁用报警,并在活动停止时重新启用它

    或者,以原子方式执行更新(例如,在表的副本上执行更新,然后在事务中同步表),以便在更新发生时活动仍然可以安全地访问数据库

    什么是“正确”的方法 正确等待(可能与状态相同) 更新)在这种情况下

    让服务在更新完成时通过某种回调或广播意图告知活动。保持进度指示器处于活动状态,直到发生这种情况。这仍然带来了一些时间上的挑战,这就是为什么我要放弃这个需求。

    感谢Mark(一如既往)提供了有用的见解。在这里,我将概述(在我看来)应该如何完成上述场景:

  • 只需绑定到服务并开始等待,而不是戳数据库
  • 如果您不能绑定到服务,那么它就没有运行,因此没有必要使用它-只需查询数据库并执行您需要的操作
  • 当服务启动时,开始等待并处理服务返回的任何反馈。这些可以是临时更新,然后是服务完成的最终指示器

  • 我的想法是一样的。我不能推迟更新,因为用户可以在更新已在进行时启动活动。因此,我将进行翻转(这是不同的问题),在更新完成之前向用户提供过时的数据。然而,仍然存在两个问题:1。用户首次安装应用程序后的初始更新如何?在这一点上没有什么可翻转的,因为我还没有旧的数据2。我为用户提供了强制刷新的能力。此时,我需要向用户显示更新正在进行中“因为我还没有旧数据,所以现在没有什么可翻转的”::耸耸肩::查看表是否为空,跳过翻转,或者其他什么。“在这一点上,我需要向用户显示更新正在进行”——使用我答案最后一段中的技巧。时间问题消失了(我认为),因为用户启动刷新。跳过翻转是显而易见的。。。事实上,我刚刚想出了一个主意,不用让用户在查看进度对话框时等待,我可以增量地添加到ListView中(同时在底部显示更新指示器)。该服务可以将更新传回工作的视图。在我的一本书中,我举了一个使用AsyncTask的例子(虽然不是从服务到活动),你甚至不需要绑定到服务。如果这是您的所有应用程序,您可以拥有一个包含指向服务指针的静态文件,该文件在service.onCreate()中设置,在service.onDestroy()中清除。然后,当您的活动想要与该服务交互时,查看静态,如果非null,则使用它。实际上,我使用匿名广播接收器进行编码,因为我不必从活动到服务进行通信