Ruc*_*nia 7 testing algorithm service android adb
我已经阅读了关于这个主题的每个Stackoverflow答案,但它们都没有奏效.
问题:每当我的设备处于睡眠模式一小时或更长时间时,服务就会被终止
返回START_STICKY从onStartCommand()使用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;
}
Run Code Online (Sandbox Code Playgroud)这样工作正常,它甚至可以在设备内存不足时重新启动我的服务,但这还不足以解决我的设备暂停一段时间后出现的问题.
在onCreate()我的Activity和onStartCommand()我的服务中使用Alarm Manager 来调用调用我的服务的广播接收器
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
Run Code Online (Sandbox Code Playgroud)这有助于保持我的服务活跃,但同样,不能解决我的问题
使用Schedule Task Executor使其保持活动状态
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
}
}
Run Code Online (Sandbox Code Playgroud)
这也只是使服务保持活动状态,但在长时间睡眠后不会保持活动状态.
单独的任务清单
android:launchMode="singleTop"
这没什么
我怎样才能(1)测试这个问题,而不必让我的手机进入睡眠状态并每小时检查一次,以及(2)尽管设备进入睡眠状态仍然保持我的服务正常运行?
Khe*_*raj 15
您的服务被Android的Doze或待机模式杀死.这是在Android 6.0(API级别23)中引入的.
打盹限制
在Doze中,以下限制适用于您的应用:
- 网络访问被暂停.
- 系统忽略唤醒锁定.
- 标准
AlarmManager报警(包括setExact()和setWindow())将推迟到下一个维护窗口.- 如果您需要设置在Doze中触发的警报,请使用
setAndAllowWhileIdle()或setExactAndAllowWhileIdle().- 设置的警报
setAlarmClock()继续正常启动 - 系统在警报触发前不久退出Doze.- 系统不执行Wi-Fi扫描.
- 系统不允许同步适配器运行.系统不允许
JobScheduler运行.
所以系统忽略你的Alarm Clocks, Scheduler等等
为了改善用户体验,Android 8.0(API级别26)对应用程序在后台运行时可以执行的操作施加了限制.
如果应用程序需要始终运行其服务,那么我们可以创建前台服务.
后台服务限制:当应用程序处于空闲状态时,其后台服务的使用受到限制.这不适用于前景服务,这对用户来说更加明显.
所以创建一个前台服务.在服务运行期间,您将在其中为用户发出通知.看到这个答案(还有很多其他的)
现在如果您不想要服务通知怎么办?解决方案就是这样.
您可以创建一些定期任务来启动您的服务,服务将完成其工作并自行停止.这样您的应用程序将不被视为电池耗尽.
您可以使用Alarm Manager,Job Scheduler,Evernote-Jobs或Work Manager创建定期任务.
我使用Work-Manager创建了永远运行的服务,这是完美的.
谋杀之谜已经解决,我知道是什么扼杀了我的服务.这是我做的:
startsticky,startforeground,alarmmanager,scheduleTaskExecutor,甚至 wakelock无法拯救我的服务,我意识到凶手不可能是Android系统,因为我已经采取了一切可能的措施,以防止系统杀死我的服务,它仍然会被打死. 我意识到我需要寻找另一个嫌疑人,因为该服务并没有因为系统而死亡.为此,我不得不进行调查.我运行了以下命令:
adb shell dumpsys activity processes > tmp.txt
这将为我提供所有正在运行的进程及其系统优先级的详细日志.从本质上讲,tmp.txt将是这个谋杀之谜中的侦探.
我仔细查看了文件.看起来系统正确地优先处理了我的服务:
Proc #31: adj=prcp /FS trm= 0 2205:servicename.service/uID (fg-service)
以上行表示在Android设备上运行的进程的确切优先级.adj=prcp表示该服务是可见的前台服务.
此时,我意识到我的服务必须在运行几个小时后遇到一些错误,所以我让它运行并死亡.它死后,我dumpsys再次制作了一个来检查错误:
tmp.txt文件中列为任务.兴奋,我滚动到底部dumpsys,解开了神秘面纱!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)在android.os.Handler.dispatchMessage(Handler.java:95)的android.app.Looper.loop(Looper.java:154)在android.app.ActivityThread.main(ActivityThread.java:6123)的java.来自com.android.internal.os.ZygoteInit.main的com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:867)中的lang.reflect.Method.invoke(Native Method)(ZygoteInit.java:757 )
导致我的服务被杀的堆栈跟踪就在那里显示了!从本质上讲,检查正在使用的前台应用程序的变量将在几个小时不活动后变为空,这将导致异常,并终止服务!
关键要点:
如果您的服务被杀,并且您已经尽了一切可以确保它不会被杀死,请执行dumpsys并检查设备活动过程的细节.我保证你会发现这个问题.
我仍然希望将奖金授予@Khemraj,因为对于那些没有正确开始服务的人来说,他的答案可能是一个很好的解决方案.但是,我接受这个答案,因为它是实际解决问题的解决方案.
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |