SecurityException:不允许启动Service

时间:2018-02-22 14:42:29

标签: android android-service android-lifecycle

在我们的应用中,我们以这种方式定义服务

<service
    android:name="ServiceName"
    android:exported="false" />

当调用活动onCreate()时,应用启动此服务。一切都很好,直到它被移动到背景很长一段时间。将应用程序移动到前台后,再次调用 onCreate(),并且应用程序尝试启动服务但收到错误:

  

引起:java.lang.SecurityException:不允许在未经uid 10156导出的情况下启动服务Intent {act = action_name cmp = app_bundle / service_name}

应用程序崩溃,重启后一切正常。我真的无法解决出错的问题。看起来 Activity 是以新的uid启动的,但是尝试与另一个进程中的 Service 与另一个uid(????)进行交互。

崩溃仅在华硕手机, Android 6.0.0上重现。

2 个答案:

答案 0 :(得分:1)

  

看起来 Activity 以新的uid启动,但尝试与另一个进程中的 Service 进行交互uid(??? ?)

我相信你已经回答了自己的问题。

  

一切都很好,直到它被移动到背景很长一段时间。

“很长时间”期间,您的应用程序(分配了uid 10XXX)在第一个位置启动服务可能已被系统杀死。您的服务可能会从其onStartCommand()返回 START_STICKY 或类似的标记,因此当应用程序进程被终止时,服务在新流程,由系统指定了另一个uid

然后,当您将应用程序带回前台时,它会在一个全新的过程中运行(意味着系统分配了另一个uid)。在其中一个活动onCreate()中,您启动了具有android:exported="false"服务,并且此时它是从另一个{{1}内调用的抛出uid这样的行为可能只是你的华硕电话专用 - 我建议用其他供应商的手机查看行为)。

答案 1 :(得分:0)

如果服务已经在onCreate()中运行,您应该添加一项检查,这样您就不会为您的服务提供双重条目。我想这个异常是由它造成的。

检查的方法之一

I use the following from inside an activity:

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

我用它来称呼它:

isMyServiceRunning(MyService.class)

Src