后台服务导致崩溃 [英] Background services causing crash

查看:138
本文介绍了后台服务导致崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题可能是对服务及其使用的过分误解,或与其他应用程序发生冲突.当我开始一个特定的活动时,我将启动两个后台服务-跟踪位置以提供行进的距离,以及经过的计时器,这两个服务都通过BroadcastReceiver传递给活动.我从主ActivityIntent对象通过Long启动每个服务:

My issue might be blatent misunderstanding of services and my use of them, or a poss conflict with other apps. When I start a specific activity, I start two background services - location tracking to give distance travelled, and elapsed timer, both of which are passed to the activity with a BroadcastReceiver. I initiate each service with a Long through the Intent object from my primary Activity:

if (!Utils.isServiceRunning(this, TrackService.class)) {
    Intent i = new Intent(this, TrackService.class);
    i.putExtra("SUB_ID", submissionID);
    startService(i);
}

然后我使用以下代码来检测服务是否已在运行:

And I use the following code to detect if the service is already running:

public static boolean isServiceRunning(Activity activity, Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

下面是onStartCommand的示例:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    submissionID = intent.getLongExtra("SUB_ID", 0L);
    // I then use this submissionID to get other data

    super.onStartCommand(intent, flags, startId);
    return START_STICKY;
}

在某些设备上,这似乎可以完美运行-该服务在后台运行,使我可以在应用程序中使用其他活动&也可以进入和退出该应用程序,当我下次打开我的特定活动时,距离和时间将更新并正确.

On some devices this seems to work perfectly - The service(s) works in the background, allowing me to use other activities in the app & also drop in and out of the app, and when I next open my specific activity, the distance and time are updated and correct.

但是,我收到大量崩溃报告,并且来自用户的轶事证据表明,这是我退出应用程序以使用相机后(我尚未确定我的应用程序崩溃是否发生在使用其他应用程序时,或者当他们重新输入我的应用程序时):

However, I'm getting lots of crash reports, and anecdotal evidence from users suggests it's after dropping out of my app to use the camera (I've yet to ascertain whether the crash in my app happens while using the other app, or when they re-enter my app):

Fatal Exception: java.lang.RuntimeException: Unable to start service edu.cornell.birds.ebird.services.TrackService@3f77db78 with null: java.lang.NullPointerException: Attempt to invoke virtual method 'long android.content.Intent.getLongExtra(java.lang.String, long)' on a null object reference
   at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3149)
   at android.app.ActivityThread.access$2500(ActivityThread.java:165)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5669)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'long android.content.Intent.getLongExtra(java.lang.String, long)' on a null object reference
   at edu.cornell.birds.ebird.services.TrackService.onStartCommand(TrackService.java:102)
   at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3112)
   at android.app.ActivityThread.access$2500(ActivityThread.java:165)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1515)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5669)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

在我看来,由于某种原因,服务正在停止,并且在重新启动时无法从意图中访问数据(我了解NullPointer错误是什么).这是因为我要返回的START_STICKY在重新启动时返回空数据吗?

It seems to me that for some reason the service is stopping, and when restarting cannot access the data from the intent (I understand what a NullPointer error is). Is this because I'm returning START_STICKY which returns null data on a restart?

有人知道服务停止的任何原因吗?以及如何防止这种情况发生?

Does anyone know of any reason why the service should be stopping? And how I can prevent this happening?

我无法使用自己的设备(Moto G4,Android 7.0)在我希望的设备上重新创建.

I'm unable to recreate using my own device (Moto G4, Android 7.0), where it works as I hoped it would.

推荐答案

Android可以(并且将)随时停止您的Service.由于您已经从onStartCommand()返回了START_STICKY,因此Android应该在杀死Service之后重新启动它.在这种情况下,重新启动后,您将在onStartCommand()中得到一个空的Intent.如果有必要,无法阻止Android杀死您的Service.

Android can (and will) stop your Service whenever it wants to. Because you have returned START_STICKY from onStartCommand(), Android should restart your Service after it has been killed. In this case you will get a null Intent in onStartCommand() after the restart. There is no way to prevent Android from killing your Service if it wants to.

您需要定期将任何有用的数据保存在永久性存储(SharedPreferences,文件,数据库等)中,以便在重新启动后可以恢复.

You need to save any useful data in a persistent storage (SharedPreferences, file, database, etc.) on a regular basis so that you can recover after being restarted.

这篇关于后台服务导致崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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