我有一个与我的真实应用相比,它在单独的过程上运行的Android服务(ServCie界面的实现)。不幸的是,当我离开真正的应用程序(在其中单击按钮以启动我的服务)并从任务管理器刷出它时,我的服务也被杀死。
我知道这里有很多类似的问题,但是以某种方式没有针对我的混凝土星座的问题,否则它们被隐约地回答。
所以在我的清单上,我有类似的东西:
<application ...>
<activity .../>
<service Android:name="MyService"
Android:label="MyLabel"
Android:export="false"
Android:process=":MyRemoteProcessName" />
</application>
我首先玩了一个意图服务,但也切换到自己的服务界面的实现(消除意图服务为失败点),看起来像:
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);
}
}
}
我在特殊按钮上以明确的意图在OnClick-Listener中启动我的服务,其中有点如下:
@Override
public void onClick(View v) {
Intent i = new Intent(this, MyService.class);
startService(i);
}
我的目的是在用户离开应用程序时保持服务运行,以便服务可以完成下载和存储一些重要数据。当用户再次回到我的应用程序时,他可以查看数据(这就是为什么我在单独的过程中执行它的原因)。所以这可能吗?
我现在的假设是,Android以某种方式注意到我的服务仅由我的应用使用(由于清单或明确调用中缺少IntentFilters而不是通过过滤器?!),因此当我的应用程序关闭时立即将其杀死(即使在上面看到的前景服务作为前景服务时)。
对您来说似乎有可能吗?可能会在服务的调用中进行一些更改解决此问题,还是我弄错了服务的概念?
(最后一个注:onlowMemory -method未被调用 -> no log条目。)
,因此,根据您的提示(和因此,我要寻找的新关键字),经过一些亲自研究,我认为我解决了自己的问题。在我的研究中,我发现了有关此主题的一篇非常相互的博客文章,也许也适合您,这就是为什么我想与您分享:http://workshop.alea.net/post/post/2016/06/android--服务杀害/。
验证并仔细研究了本文中的步骤,一切似乎都很好(因此开始前景似乎可以解决问题)。我想在这里指出,我只对其进行了测试,而我的服务实例仍在单独的过程中运行,因此显示了上述条目。
一开始真的让我感到困惑的实际事情是我的Android Studio调试会话每次都会被杀死,只是在从最近的应用程序(菜单)中刷出我的应用程序之后。这使我认为我的服务也被系统杀死。但是根据文章(我已经在提供的回调方法中添加了一些日志)
时打开我的应用
开始服务
扫除应用程序
再次启动应用,最后
再次致电服务,
我只收到了对方法的回调,就好像我的服务仍在运行一样。对DDMS(工具)的明确查看也证明了我的第二个过程,因此我的服务仍然活着。验证了这一点后,我清除了所有应用程序数据并重复上述步骤(不包括第5步)。之后查看了数据库后,就证明了该服务已下载的数据。
对您的好奇:
从最近的应用程序中刷出我的应用程序的过程(因此,称为OnTaskRemed回调方法)导致另一个问题。它以某种方式将OnstartCommand的startID参数增加1个,以使我的延迟施加QuectRequest出现故障,并且不再停止我的服务。
这意味着:在第1-3步中重复上述步骤1-3使我在onstartCommand中接收startid = 1。通过稍后(最新的开始ID)调用stopelfresult(1),它将返回false,并且服务继续运行。然后继续遵循步骤4 5,然后将OnstartCommand命名为StartID = 3(但实际上应该是2!它以某种方式跳过)。稍后使用参数3的呼叫stopelfresult(3)然后再次停止服务(在屏幕截图中也可见)。
我希望到目前为止我的答案是正确的(可以理解的),对您也有帮助。感谢您提供的所有答案,这些答案提供了有益的意见,也将我指向了解决方案。我一直使用的Android版本是:
4.1.2-果冻豆|API级别:16
我还添加了DDMS的日志条目的屏幕截图(Imgur拒绝我的上传,因此您将暂时具有指向我的Dropbox的链接):来自DDMS
的日志中的屏幕截图不幸地在单独的过程中运行服务对您没有帮助。我认为,如果用户删除其任务,您无法阻止您的服务关闭。但是,您可以重新启动服务覆盖的OnTaskRemped。请参阅此答案。
如果要在关闭应用程序后无限期地运行此服务类。
public void scheduleAlarm() {
// Construct an intent that will execute the AlarmReceiver
Intent intent = new Intent(this, LocationListnerServiec.class);
// Create a PendingIntent to be triggered when the alarm goes off
final PendingIntent pIntent = PendingIntent.getBroadcast(this, MyAlarmReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup periodic alarm every 5 seconds
long firstMillis = System.currentTimeMillis(); // alarm is set right away
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
// First parameter is the type: ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC_WAKEUP
// Interval can be INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_DAY
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
60000, pIntent);
}
使用此方法继续检查服务类是打开或关闭的。通过使用此方法,您的服务类将在销毁您的应用程序后继续工作。