android - 与前台服务反应本机 - 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>
解决方案
推荐阅读
- javascript - 无需身份验证将数据写入 Firebase 实时数据库中的字段
- html - 在图像上添加平滑渐变滤镜
- php - 灯泡服务器中的碳投掷错误
- swift4.1 - URLSession.shared.dataTask 在没有 .resume() 的情况下无法工作
- angular - 在科尔多瓦离子本机应用程序中为openID连接指定重定向uri的位置
- c# - 如何在 FluentValidation 的世界中使用带有 ValidateAsync 的规则集?
- python - 过滤满足一组标准的多对多关系
- asp.net - 可以将纯文本密码发送到服务器端进行身份验证吗?避免这种纯文本传输的常用方法是什么
- symfony - Symfony 4 - Lexik/JwtAuthenticationBundle - 无法更改 token_ttl 默认值
- html - 如何在输入中进行 Html 电子邮件验证?