前台服务onTaskRemoved发送广播Intent android.os.DeadObjectException失败

时间:2015-12-19 16:04:08

标签: android cordova webview android-service locationmanager

我正在开发https://github.com/mauron85/cordova-plugin-mauron85-background-geolocation-phonegapbuild

基本上它是使用LocationManager将位置发送到webview的cordova插件。

核心实现为android.app.Service,它在前台启动,以减少被os杀死的可能性。

服务也有自己的进程(android:process =":remote")。 因此服务将主要活动(线程)杀死或用户关闭的应用程序。即使被杀死,它也会通过在onStartCommand中设置标志START_REDELIVER_INTENT来自动重启。

我的问题是,在应用程序关闭后(从任务lisk中删除),服务在几秒钟后崩溃。在日志中我看到:

digitalClockProcess := [[

       Processor sleep: 1000.

       (View desktop canvas)

               font: (Font name: 'Arial' pointSize: 36) beBold;

               text: Time now printString at: 10@10;

               free

] repeat] fork.

然后经过一段时间(97188832ms)服务重新启动并正常运行。但为什么它在第一时间坠毁?当服务存在于自己的线程中时,为什么发送广播失败?为什么它会在自动重启后再次崩溃?

3 个答案:

答案 0 :(得分:1)

我建议您在DistanceFilterLocationService.java的onCreate()代码中查看这些行(或因此而触发的任何意图):

...
// Stationary region PI
stationaryRegionPI  = PendingIntent.getBroadcast(this, 0, new Intent(STATIONARY_REGION_ACTION), PendingIntent.FLAG_CANCEL_CURRENT);
registerReceiver(stationaryRegionReceiver, new IntentFilter(STATIONARY_REGION_ACTION));
...

根据registerReceiver(BroadcastReceiver receiver, IntentFilter filter)的官方文档:

  

注册要在 主要活动主题 中运行的BroadcastReceiver。   接收器将与任何匹配的广播Intent一起调用   过滤器,主应用程序线程中的

基本上,stationaryRegionReceiver的{​​{1}}将在主UI线程上运行,如果您的应用关闭,该线程应该消失。 请改为探讨这一点,registerReceiver (BroadcastReceiver receiver, IntentFilter filter, Handler handler)

您还可以使用此帖子来测试运行代码的一部分线程: How to check if current thread is not main thread

答案 1 :(得分:1)

我认为原因是this bug

Android的最新版本中存在错误,其中没有任何绑定到活动的服务将在他们收到任何Intent广播时被杀死(无论服务是否在单独的进程中)。有一些丑陋的解决方法(实际上我自己制作了一个),但我真的不能推荐。谢天谢地,android自动重启服务一段时间后。

答案 2 :(得分:0)

我有点晚了,但也许它对某人有用。我发现这可能是与KitKat和更新版本相关的问题。解决方法是使用以下代码:

AlarmManager manager = (AlarmManager) MyContext.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(MyContext, MyBroadcastReceiver.class);
alarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
PendingIntent myPendingIntent = PendingIntent.getBroadcast(MyContext, 1, alarmIntent, 0);

我读了一些关于副作用的内容,但我对上述解决方案没有任何问题。

参考:Issue 53313