服务在睡眠模式下被杀死.为什么? [英] Service is killed in sleep mode.Why?

查看:27
本文介绍了服务在睡眠模式下被杀死.为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了有关该主题的几乎所有 Stackoverflow 答案,但没有一个有效.

目标:让我的服务全天候 24/7 运行

问题:每当我的设备处于睡眠模式一个小时或更长时间时,服务就会被终止

<小时>

我试图解决的问题:

  • onStartCommand() 返回 START_STICKY 并使用 startForeground()

     public int onStartCommand(Intent intent, int flags, int startId) {通知 = makeStickyNotification();//我已经简化了不相关的代码,显然这将是我构建的一个真正的通知startForeground(1234, 通知);返回 START_STICKY;}

这很好用,它甚至会在设备内存不足时重新启动我的服务,但不足以解决我的设备进入睡眠状态一段时间后出现的问题.

  • 在我的活动的 onCreate() 和我的服务的 onStartCommand() 中使用警报管理器来调用调用我的服务的广播接收器

     Intent ll24 = new Intent(this, AlarmReceiver.class);PendingIntent recurringLl24 = PendingIntent.getBroadcast(this, 0, ll24, PendingIntent.FLAG_CANCEL_CURRENT);AlarmManager 警报 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);alarms.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000*60, recurringLl24);//每一分钟

这有助于使我的服务保持活跃,但同样不能解决我的问题

  • 使用 Schedule Task Executor 使其保持活动状态

     if (scheduleTaskExecutor == null) {scheduleTaskExecutor = Executors.newScheduledThreadPool(1);scheduleTaskExecutor.scheduleAtFixedRate(new mainTask(), 0, 1, TimeUnit.SECONDS);}...类 mainTask 实现 Runnable {公共无效运行(){//1 秒定时器}}

    这也只是保持服务处于活动状态,但在长时间睡眠后不会使其保持活动状态.

  • 单独的任务清单

    android:launchMode="singleTop"

什么都没做

我如何 (1) 测试此问题而不必让手机进入睡眠状态并每小时检查一次,以及 (2) 在设备进入睡眠状态时仍保持服务运行?

解决方案

谋杀之谜已经解开,我知道是什么杀死了我的服务.这是我所做的:

  1. 在我意识到startstickystartforegroundalarmmanagerscheduleTaskExecutor甚至strong> wakelock 无法保存我的服务,我意识到凶手不可能是Android系统,因为我已经采取了一切可能的措施来防止系统杀死我的服务并且它仍然会被杀死.
  2. 我意识到我需要寻找另一个嫌疑人,因为服务并没有因为系统而死亡.为此,我不得不进行调查.我运行了以下命令:

    adb shell dumpsys 活动进程>tmp.txt

这将为我提供所有正在运行的进程及其系统优先级的详细日志.本质上,tmp.txt 将成为这个谋杀之谜的侦探.

  1. 我仔细查看了文件.系统似乎对我的服务进行了适当的优先排序:

    Proc #31: adj=prcp/FS trm= 0 2205:servicename.service/uID (fg-service)

上一行表示在 Android 设备上运行的进程的确切优先级.adj=prcp 表示该服务是一个可见的前台服务.

此时,我意识到我的服务一定在运行几个小时后遇到了一些错误,所以我让它运行并死亡.它死后,我再次生成一个dumpsys 来检查错误:

  1. 此时,我的服务未在 tmp.txt 文件中列为任务.兴奋的我滚动到 dumpsys 的底部并解开了谜团!

<块引用>

com.curlybrace.ruchir.appName.MyService$2.onForeground(MyService.java:199)在 com.rvalerio.fgchecker.AppChecker$2.run(AppChecker.java:118)在 android.os.Handler.handleCallback(Handler.java:751)在 android.os.Handler.dispatchMessage(Handler.java:95)在 android.os.Looper.loop(Looper.java:154)在 android.app.ActivityThread.main(ActivityThread.java:6123)在 java.lang.reflect.Method.invoke(Native Method)在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

导致我的服务被终止的堆栈跟踪显示在那里!本质上,用于检查正在使用的前台应用程序的变量会在几个小时不活动后变为空值,这将导致异常并终止服务!

关键要点:如果您的服务被终止,并且您已尽一切努力确保它不会被终止,请执行 dumpsys 并检查设备活动过程的细节.我保证你会通过这种方式找到问题.

我仍然希望将赏金授予@Khemraj,因为他的回答对于没有正确启动服务的人来说可能是一个很好的解决方案.但是,我接受这个答案,因为它是实际解决问题的解决方案.

I've read just about every Stackoverflow answer that exists on this topic, but none of them worked.

Goal: Keep my service running 24/7, all the time

Problem: Whenever my device is on sleep mode for an hour or more, the service is killed


What I've tried to fix it:

  • Returning START_STICKY from onStartCommand() and using startForeground()

        public int onStartCommand(Intent intent, int flags, int startId) {
    
            notification = makeStickyNotification(); //I've simplified the irrelevant code, obviously this would be a real notification I build
    
            startForeground(1234, notification);
            return START_STICKY;
            }
    

This works fine, and it even restarts my service whenever the device is low on memory, but it is not enough to fix the problem that occurs when my device goes to sleep for a while.

  • Using Alarm Manager in onCreate() of my Activity and in onStartCommand() of my Service to call a Broadcast Receiver that calls my service

            Intent ll24 = new Intent(this, AlarmReceiver.class);
    
            PendingIntent recurringLl24 = PendingIntent.getBroadcast(this, 0, ll24, PendingIntent.FLAG_CANCEL_CURRENT);
    
            AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    
            alarms.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000*60, recurringLl24); // Every minute
    

This helps keep my service active, but again, doesn't solve my problem

  • Using Schedule Task Executor to keep it alive

     if (scheduleTaskExecutor == null) {
    
            scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
    
            scheduleTaskExecutor.scheduleAtFixedRate(new mainTask(), 0, 1, TimeUnit.SECONDS);
    
        }
    ...    
    class mainTask implements Runnable {
    
    public void run() {
        // 1 Second Timer
       }
    }
    

    This also just keeps the service active but doesn't keep it alive after a long sleep.

  • Separate task Manifest

    android:launchMode="singleTop"

This did nothing

How can I (1) test this issue without having to put my phone to sleep and check every hour and (2) keep my service running despite the device going to sleep?

解决方案

The murder mystery has been solved, and I know what killed my service. Here's what I did:

  1. After I realized that startsticky, startforeground, alarmmanager, scheduleTaskExecutor, and even wakelock were unable to save my service, I realized the murderer couldn't be the Android system, because I had taken every measure possible to prevent the system from killing my service and it still would get killed.
  2. I realized I needed to look for another suspect, since the service wasn't dying because of the system. For that, I had to run an investigation. I ran the following command:

    adb shell dumpsys activity processes > tmp.txt

This would give me a detailed log of all the processes running and their system priorities. Essentially, tmp.txt would be the detective in this murder mystery.

  1. I looked through the file with lots of detail. It looked like my service was prioritized properly by the system:

    Proc #31: adj=prcp /FS trm= 0 2205:servicename.service/uID (fg-service)

The above line indicates the exact priority of a process running on the Android device. adj=prcp means the service is a visible foreground service.

At this point, I realized that my service must be encountering some error a couple hours after running, so I let it run and die. After it died, I produced a dumpsys again to examine the error:

  1. At this point, my service wasn't listed as a task in the tmp.txt file. Excited, I scrolled to the bottom of the dumpsys and solved the mystery!

com.curlybrace.ruchir.appName.MyService$2.onForeground(MyService.java:199) at com.rvalerio.fgchecker.AppChecker$2.run(AppChecker.java:118) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

The stack trace that caused the killing of my service was displayed right there! Essentially, a variable that would check for the foreground app being used would become null after a few hours of inactivity, which would cause an exception, and kill the service!

Key Takeaways: If your service is getting killed, and you've done everything you can to make sure that it shouldn't be killed, perform a dumpsys and examine the nitty gritty of your device's activity process. I guarantee you will find the issue that way.

I still would like to have the bounty awarded to @Khemraj since his answer could be a great solution for someone who hasn't started their service properly. However, I am accepting this answer since it is the solution that actually fixed the issue.

这篇关于服务在睡眠模式下被杀死.为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆