美文网首页
Not allowed to start service Int

Not allowed to start service Int

作者: 程序员Android1 | 来源:发表于2020-12-31 09:46 被阅读0次

    一、Crash Log

    FATAL EXCEPTION: Thread-13
    Process: xxxx , PID: 12962
    java.lang.IllegalStateException: Not allowed to start service Intent { flg=0x20 cmp=com.***/***android.service.DaemonService }: app is in background uid null
    at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1701)
    at android.app.ContextImpl.startService(ContextImpl.java:1657)
    at android.content.ContextWrapper.startService(ContextWrapper.java:644)
    at cn.jpush.android.service.l.run(Unknown Source:108)
    at java.lang.Thread.run(Thread.java:784)
    

    二、问题原因:

    App targetSdkVersion>= 26的情况下,用户允许App开机自启动,App被杀死或者系统重启后,系统直接将App后台启动起来,App在后台启动的过程中有使用startService()方法。

    Google在Android 8.0之后对于处于后台的App启动Service进行了严格的限制,不再允许后台App启动后台Service,如果使用会直接抛出异常。

    三、 解决方案

    1. app端

    使用startForegroundService,此方法会在状态栏显示通知

    // 启动服务的地方
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(new Intent(context, MyService.class));
    } else {
        context.startService(new Intent(context, MyService.class));
    }
    
    // 在MyService中
     
    @Override
    public void onCreate() {
        super.onCreate();
     
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel channel = null;
            channel = new NotificationChannel(CHANNEL_ID_STRING, getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
            Notification notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID_STRING).build();
            startForeground(1, notification);
        }
     
    }
    
    2.源码白名单

    可以在E:\AOSP\android_10_0_0_r40\frameworks\base\services\core\java\com\android\server\am\ActiveServices.java 中添加白名单。

    public final class ActiveServices {
    ... ...
        ComponentName startServiceLocked(...)
                throws TransactionTooLargeException {
      ...
    
             // If this isn't a direct-to-foreground start, check our ability to kick off an
            // arbitrary service
            if (forcedStandby || (!r.startRequested && !fgRequired)) {
                // Before going further -- if this app is not allowed to start services in the
                // background, then at this point we aren't going to let it period.
                final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
                        r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
                //add Background start service white list
                boolean isBackgroundStartServiceWhiteList="com.xxx.xxx".equals(callingPackage);
                //add Background start service white list   
                if (allowed != ActivityManager.APP_START_MODE_NORMAL && !isBackgroundStartServiceWhiteList ) {
                    Slog.w(TAG, "Background start not allowed: service "
                            + service + " to " + r.shortInstanceName
                            + " from pid=" + callingPid + " uid=" + callingUid
                            + " pkg=" + callingPackage + " startFg?=" + fgRequired);
                    if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
                        // In this case we are silently disabling the app, to disrupt as
                        // little as possible existing apps.
                        return null;
                    }
    }
      ...
    
    }
    ... ...
    }
    

    相关文章

      网友评论

          本文标题:Not allowed to start service Int

          本文链接:https://www.haomeiwen.com/subject/melloktx.html