【问题标题】:App seems to be in background when activity onStart is called调用活动 onStart 时,应用程序似乎在后台
【发布时间】:2019-03-24 07:41:54
【问题描述】:

从 Android Oreo 开始,当应用不在前台时,您无法启动服务。在我的应用程序中,我在活动的 onStart 方法中启动了一项服务。这在大多数情况下都可以正常工作。但是,有时会抛出 IllegalStateException,说明应用程序正在后台尝试启动服务:

    java.lang.IllegalStateException: Not allowed to start service Intent { act=ui cmp=com.someapp/.services.ConnectionService }: app is in background uid UidRecord{8d70361 u0a255 TPSL bg:+3m12s948ms idle change:cached procs:1 proclist:20368, seq(0,0,0)}
    at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1666)
    at android.app.ContextImpl.startService(ContextImpl.java:1611)
    at android.content.ContextWrapper.startService(ContextWrapper.java:677)
    at com.someapp.ui.SomeActivity.connectToBackend(SomeActivity.java:62)
    at com.someapp.ui.SomeActivity.onStart(SomeActivity.java:55)
    at com.someapp.ui.MainActivity.onStart(MainActivity.kt:228)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
    at android.app.Activity.performStart(Activity.java:7348)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3131)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1947)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7032)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

我启动服务如下:

@Override
protected void onStart() {
    if (BuildConfig.DEBUG_MODE) Log.d(TAG, "activity started");
    super.onStart();
    connectToBackend();
}

void connectToBackend() {
    Intent intent = new Intent(this, ConnectionService.class);
    intent.setAction("ui");
    startService(intent);
    getApplicationContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

我注意到只有当我在应用程序中锁定然后解锁手机时才会发生这种情况。我无法始终如一地重现它。

有人有同样的问题吗?

我使用的设备是三星 Galaxy S10e。

【问题讨论】:

  • 代码需要添加
  • 正如我在here 上评论的,你们为什么有服务?服务适用于当您的 UI 处于前台时您需要工作的情况。普通 Java/Kotlin 对象无法满足的服务价值是什么?
  • 该应用程序是一个消息应用程序,因此大多数时候它的 UI 不在前台。我使用该服务来处理与服务器的连接。服务对于启动服务的传入 fcm 消息很有用。此外,当用户在 VoIP 通话中离开应用程序时,需要该服务在后台处理连接。

标签: android samsung-mobile android-8.0-oreo


【解决方案1】:

对于牛轧糖后设备,使用startForegroundService,对于奥利奥前设备,使用startService

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent);
} else {
    startService(intent);
}

【讨论】:

  • 没有人希望在进入应用程序时看到前台通知。此外,前台服务的想法是向用户显示应用程序正在后台执行某些操作,而不是在用户进入应用程序时启动。
  • 我刚刚提到了对奥利奥设备施加的限制,以及您问题的唯一可能解决方案。
  • 重点是虽然应用在前台,但由于服务绑定在onStart中,还是出现了错误。显然发生了一些竞争情况。至少有两种快速的解决方案或更好的解决方法:(i)在 onResume 中启动服务(未测试); (i) 延迟启动服务 200 毫秒(我最终实现的)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多