Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当我刷出我的应用程序(在其他进程中运行)时,在单独进程上运行的Android服务被终止_Android_Android Service_Long Running Processes_Foreground Service - Fatal编程技术网

当我刷出我的应用程序(在其他进程中运行)时,在单独进程上运行的Android服务被终止

当我刷出我的应用程序(在其他进程中运行)时,在单独进程上运行的Android服务被终止,android,android-service,long-running-processes,foreground-service,Android,Android Service,Long Running Processes,Foreground Service,我有一个Android服务(Servcie接口的实现),与我的真实应用程序相比,它运行在一个单独的进程上。不幸的是,当我离开我真正的应用程序(在该应用程序中,我单击按钮启动我的服务)并从任务管理器中将其刷出时,我的服务也被终止 我知道这里有很多这样的问题,但不知何故,在我的具体星座中,没有一个是针对这个问题的,或者答案模糊 所以在我的清单中我有这样的东西: <application ...> <activity .../> <service Andr

我有一个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侦听器中启动我的服务,具有明确的意图,类似于以下内容:

@Override
public void onClick(View v) {
    Intent i = new Intent(this, MyService.class);
    startService(i);
}
我的意图是在用户离开应用程序时保持服务运行,以便服务能够完成下载和存储一些重要数据。当用户再次返回到我的应用程序时,他可以查看数据(这就是为什么我要在单独的过程中执行它)。那么这可能吗

我现在的假设是,Android不知何故注意到我的服务正被我的应用程序使用(由于清单或显式调用中缺少IntentFilters,而不是filter?!),因此当我的应用程序关闭时(即使在作为ForegroundService运行时,正如上面所示),它会立即终止

您觉得这可能吗?服务调用中的一些更改是否可以解决此问题?或者我对服务的概念理解是否有误


(最后一点注意:onLowMemory方法不会被调用->没有日志条目。)

不幸的是,在单独的进程中运行服务对您没有帮助。我认为,如果用户删除其任务,您无法阻止您的服务关闭。但是,您可以重新启动覆盖onTaskRemoved的服务。查看此项。

如果您想在关闭应用程序后无限期运行此服务类。。您应该使用Alaram管理器类

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);
    }

使用此方法持续检查服务类是否打开。。通过使用此方法,您的服务类将在销毁您的应用程序后继续工作。

因此,根据您的提示(以及我要查找的新关键字),经过我自己的一些额外研究,我认为我已经解决了我的问题。在我的研究过程中,我发现了一篇关于这个话题的非常有趣的博文,可能也是为你写的,这就是为什么我想和你分享它:

在验证并完成本文中的步骤后,一切似乎都正常工作(因此startForeground似乎可以解决问题)。我想在这里指出,我只测试了它,我的服务实例仍在单独的进程中运行,所以清单条目如上所述

一开始真正让我困惑的是,我的android studio调试会话每次都会被终止,就在从最近的应用程序(菜单)中刷出我的应用程序之后。这让我觉得我的服务也被系统扼杀了。但是根据这篇文章(我已经在提供的回调方法中添加了一些日志),当

  • 打开我的应用程序

  • 开始服务

  • 刷出应用程序

  • 再次启动应用程序并最终启动

  • 再次呼叫服务

  • 我只收到对这些方法的回调,就好像我的服务仍在运行一样。通过对DDMS(工具)的清晰观察,也证明了我的第二个流程以及我的服务仍然有效。在验证了这一点后,我清除了所有应用程序数据,并重复上述步骤(不包括第5步)。之后查看了数据库,发现服务下载了数据

    出于好奇:

    从最近的应用程序中刷出我的应用程序(从而调用onTaskRemoved回调方法)的过程会导致另一个问题。它以某种方式将onStartCommand的startId参数增加了1,从而使我的DelayedStopRequest出现故障,不再停止我的服务

    这意味着:重复上述步骤1-3使我在onStartCommand中接收startId=1。稍后调用stopSelfResult(1)(这是最新的startId),它返回false,并且服务继续运行。然后继续执行步骤4+5,使onStartCommand以startId=3被调用(但实际上应该是2!,不知何故被跳过)。稍后使用参数3调用stopSelfResult(3)将再次停止服务(在屏幕截图中也可见)

    我希望我的回答到目前为止是正确的(,可以理解),也对你有帮助。感谢您的所有回答,这些回答提供了有益的意见,也为我指明了解决方案。我一直使用的android版本是:


    4.1.2-果冻豆| API等级:16

    我还添加了DDMS日志条目的屏幕截图(imgur拒绝我的上传,所以您将暂时有一个指向我的dropbox的链接):

    你能详细解释一下吗?这项服务通过它的onStart方法将自己置于前台,或者你的意思是不同的吗?你在测试哪个版本的Android?另外,你在测试什么设备?4.1.2-Jelly Bean | API级别:16-但我刚才也发布了一个答案。请随意查看它您正在测试什么设备?它是三星Galaxy Tab 2,可能是8G,并且从2010年开始仅支持WiFi?(我觉得它太旧了,现在几乎感到有点惭愧:p)型号说:GT-P3110真可惜!尽管它可能不是100%符合要求,但它可能是一种可接受的解决方法。我稍后会在家里试试,可能会接受这个答案(任何人都有更好的建议)。在这一点上非常感谢你!这是2020年的推荐方法吗?我相信
    WorkManager
    更好。