首页 文章

SecurityException:不允许启动Service

提问于
浏览
1

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

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

当调用Activity的 onCreate() 时,app会启动此服务 . 一切都很好,直到它被移动到背景很长一段时间 . 将app移动到前台后再次调用onCreate(),app尝试启动Service但收到错误:

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

应用程序崩溃,重启后一切正常 . 我真的不知道出了什么问题 . 看起来Activity是以新的 uid 启动的,但是尝试使用另一个进程与另一个进程进行交互 uid (????) .

Crash仅在华硕手机Android 6.0.0上重现 .

2 回答

  • 0

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

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

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

    在"long time"期间,您的应用程序(分配了 uid 10XXX)在第一个位置启动服务可能已被系统杀死 . 您的服务可能从其 onStartCommand() 返回START_STICKY或类似标志,因此当应用程序进程被终止时,服务在系统的新进程 with another uid assigned 内启动 .

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

  • 1

    您应该添加一个检查服务是否已经在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

相关问题