Seb*_*n36 5 android long-running-processes android-service foreground-service
我有一个 Android 服务(Servcie 接口的实现),与我的真实应用程序相比,它在单独的进程上运行。不幸的是,当我离开我的真实应用程序(在其中我单击按钮启动我的服务)并从任务管理器中将其刷出时,我的服务也被杀死了。
我知道这里有很多这样的问题,但不知何故,没有人在我的具体星座中针对这个问题,或者他们的回答含糊不清。
所以在我的清单中,我有类似的东西:
<application ...>
<activity .../>
<service Android:name="MyService"
Android:label="MyLabel"
Android:export="false"
Android:process=":MyRemoteProcessName" />
</application>
Run Code Online (Sandbox Code Playgroud)
我首先使用了一个 IntentService,但也切换到了自己的服务接口实现(消除了 IntentService 成为故障点),它看起来像:
public class MyService extends Service {
private ScheduledExecutorService scheduledWorker = Executors.newSingleThreadScheduledExecutor();
@Override
public void onStart() {
// Init components
startForeground(this, MyNotification);
}
@Override
public int onStartCommand(Intent i, int startId) {
// Execute Work on Threadpool here
scheduledWorker.execute(new ScheduledStopRequest(this, startId), 5, TimeUnit.Minutes);
return START_REDILIVER_INTENT;
}
// Overwritten onDestroy-Method
@Override
public void onLowMemory() {
Log.e(LOG_TAG, "On Low Memory called!");
}
@Override
public IBind onBind() {
// Dont't want to let anyone bind here
return null;
}
// Simply tries to stop the service after e.g. 5 Minutes after a call
private static class MyRunnable implements Runnable {
// Constructor with params used in run method..
@Override
public void run() {
mReferenceToMyService.stopSelfResult(startId);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在一个特殊按钮上的 onClick-Listener 中启动我的服务,具有明确的意图,它看起来像下面这样:
@Override
public void onClick(View v) {
Intent i = new Intent(this, MyService.class);
startService(i);
}
Run Code Online (Sandbox Code Playgroud)
我的意图是在用户离开应用程序时保持服务运行,以便服务可以完成下载和存储一些重要数据。当用户再次回到我的应用程序时,他可以查看数据(这就是我在单独的进程中执行它的原因)。那么这可能吗?
我现在的假设是,Android 以某种方式注意到我的服务正在被我的应用程序使用(由于缺少清单中的 IntentFilters 或显式调用而不是过滤器?!),因此在我的应用程序关闭时立即杀死它(即使在运行时)如您在上面看到的那样作为 ForegroundService )。
在您看来是否可行?服务调用中的一些更改是否可以解决此问题,或者我是否误解了服务的概念?
(最后一点:onLowMemory-Method 不会被调用 -> 没有日志条目。)
因此,根据您的提示(以及我要寻找的新关键字)并经过我自己的一些额外研究,我认为我已经解决了我的问题。在我的研究过程中,我发现了一篇关于这个主题的非常有趣的博客文章,也许也适合您,这就是为什么我想与您分享它: http: //workshop.alea.net/post/2016/06/android-服务终止/ .
在验证并完成本文中的步骤之后,一切似乎都工作正常(因此 startForeground 似乎解决了问题)。我想在这里指出,我只是测试了它,我的服务实例仍在单独的进程中运行,因此清单条目如上所述。
一开始真正让我困惑的是我的 android studio 调试会话每次都在从最近的应用程序(菜单)中刷出我的应用程序后被终止。这让我觉得我的服务也被系统杀死了。但是根据文章(我已经在提供的回调方法中添加了一些日志)当
打开我的应用程序
启动服务
刷出应用程序
再次启动应用程序,最后
再次致电服务人员,
我只收到对方法的回调,就好像我的服务仍在运行一样。明确查看 DDMS(工具)也证明了我的第二个流程,因此我的服务仍然存在。验证这一点后,我清除了所有应用程序数据并重复上述步骤(不包括步骤 5)。后来查看了数据库,证明数据已被服务下载。
对于好奇的你:
从最近的应用程序中删除我的应用程序(从而调用 onTaskRemoved 回调方法)的过程会导致另一个问题。它以某种方式将 onStartCommand 的 startId 参数增加 1,以便我的 DelayedStopRequest 发生故障并且不再停止我的服务。
这意味着:重复上述步骤 1 - 3 使我在 onStartCommand 中收到 startId = 1。通过稍后调用 stopSelfResult(1)(这是最新的 startId),它返回 false 并且服务继续运行。然后继续执行步骤 4 + 5,使用 startId = 3 调用 onStartCommand(但实际上应该是 2!以某种方式跳过)。稍后使用参数 3 调用 stopSelfResult(3) 将再次停止服务(也可以在屏幕截图中看到)。
我希望到目前为止我的回答是正确的(可以理解)并且对您也有帮助。感谢您提供的所有答案,它们提供了有益的意见,也为我指出了解决方案。我一直使用的android版本是:
4.1.2 - 果冻豆 | API 级别:16
我还添加了 DDMS 日志条目的屏幕截图(imgur 拒绝我的上传,因此您将暂时拥有指向我的保管箱的链接): 来自 DDMS 日志的屏幕截图
| 归档时间: |
|
| 查看次数: |
2087 次 |
| 最近记录: |