首页 > 解决方案 > 与前台服务反应本机 - handleWindowVisibility:令牌 android.os.BinderProxy 没有活动

问题描述

我在本机反应中创建应用程序,它需要运行包含本机代码的前台服务。该服务本身运行良好,但在终止主应用程序进程后(通过按方形按钮并将应用程序滑开) - 它有时会在从图标或通知启动时返回而没有任何并发​​症,但它通常显示空白屏幕(没有启动任何活动)并handleWindowVisibility: no activity for token android.os.BinderProxy打印日志猫。我已经在谷歌上搜索了几个小时,但是关于这件事的反馈很少,而且似乎没有什么对我有用。

我用来通过 RCT Bridge 进行交流的类

@ReactMethod
fun init() {

    val service = Intent(context, MyService::class.java)
        service.action = SERVICE_ACTION_EXECUTE

    if(!isMyServiceRunning(MyService::class.java)) {
        Log.i("MyService", "Starting new service")
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(service)
        } else {
            context.startService(service)
        }
    }

    val serviceConnection = object: ServiceConnection {
        override fun onServiceConnected(p0: ComponentName?, binder: IBinder?) {
            myService = (binder as MyService.LocalBinder).getService()
            myService?.bindClient(this@Integrator)
        }

        override fun onServiceDisconnected(p0: ComponentName?) {
            myService?.unbindClient()
        }
    }

    context.bindService(service, serviceConnection, Context.BIND_AUTO_CREATE)
}

private fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
    val manager: ActivityManager? =
        context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
    for (service in manager?.getRunningServices(Int.MAX_VALUE)!!) {
        if (serviceClass.name == service.service.className) {
            return true
        }
    }
    return false
}

我的前台服务:

@RequiresApi(api = Build.VERSION_CODES.O)
private fun createNotificationChannel() {
    val notificationManager: NotificationManager =
        getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    val name: CharSequence =
        getString(R.string.app_name)

    val channel =
        NotificationChannel(NOTIFICATION_CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW)

    notificationManager.createNotificationChannel(channel)
}

private fun buildNotification(): Notification {
    val intent = Intent(applicationContext, MainActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(applicationContext, 0, intent, 0)

    if(notificationBuilder == null) {
        notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
        notificationBuilder = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL_ID)
            .setContentTitle(getString(R.string.app_name))
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .setCategory(Notification.CATEGORY_SERVICE)
            .setOngoing(true)
    }

    // Set Exit button action
    val exitIntent =
        Intent(applicationContext, MyService::class.java).setAction(SERVICE_ACTION_STOP)

    notificationBuilder!!.addAction(
        android.R.drawable.ic_delete,
        getString(R.string.close),
        PendingIntent.getService(applicationContext, 0, exitIntent, 0)
    )
    
    return notificationBuilder!!.build()
}

override fun onCreate() {
    super.onCreate()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        createNotificationChannel()

    val notification = buildNotification()
    startForeground(NOTIFICATION_FOREGROUND_SERVICE_ID, notification)

    val action = intent?.action
    if(action != null){
        when(action) {
            SERVICE_ACTION_EXECUTE -> {
                Log.d(TAG, "Service executed")
                executor.execute(IncomingIntentRouter(intent))
            }
            SERVICE_ACTION_STOP -> {
                Log.d(TAG, "Service stopped")
                stopService()
            }
        }

    } else {
        Log.d(TAG, "Got null onStartCommand() action")
    }

    return START_STICKY
}

安卓清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.app">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

<application
  android:name=".MainApplication"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:allowBackup="false"
  android:theme="@style/AppTheme"
  android:networkSecurityConfig="@xml/network_security_config"
  android:extractNativeLibs="true">
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
    android:launchMode="singleTask"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  </activity>
  <service
      android:name=".MyService" />
</application>

标签: androidreact-nativeforeground-service

解决方案


推荐阅读