我在Android O操作系统上使用服务类。
我计划在后台使用服务。
Android文档指出
如果你的应用程序的API级别为26或更高,系统会对使用或创建后台服务施加限制,除非应用程序本身在前台。如果应用程序需要创建前台服务,应用程序应该调用startForegroundService()。
如果使用startForegroundService(),服务抛出以下错误。
Context.startForegroundService() did not then call
Service.startForeground()
这有什么问题?
我在Pixel 3和Android 11中遇到了一个问题,当我的服务运行得很短时,前台通知没有被取消。
在stopForeground() stopSelf()之前添加100ms的延迟似乎有所帮助。
人们在这里写道,stopprospect()应该在stopSelf()之前被调用。我不能确认,但我猜它不会费心去做。
public class AService extends Service {
@Override
public void onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(
getForegroundNotificationId(),
channelManager.buildBackgroundInfoNotification(getNotificationTitle(), getNotificationText()),
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
} else {
startForeground(getForegroundNotificationId(),
channelManager.buildBackgroundInfoNotification(getNotificationTitle(), getNotificationText())
);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground();
if (hasQueueMoreItems()) {
startWorkerThreads();
} else {
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
private class WorkerRunnable implements Runnable {
@Override
public void run() {
while (getItem() != null && !isLoopInterrupted) {
doSomething(getItem())
}
waitALittle();
stopForeground(true);
stopSelf();
}
private void waitALittle() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
大约有10个用户在我们的应用程序的崩溃分析中得到这个错误。
正如Kimi Chiu回答的那样:这个问题的主要原因是服务在提升到前台之前就停止了。但是断言在服务被销毁后并没有停止。你可以尝试在调用startforegroundservice后添加StopService来重现这个过程
所以我测试了这个,并得以复制。
我应用的一个解决方案是,我让服务至少停留5秒钟,这样服务就会提升到前台。现在我在测试时无法重现这个问题。
private fun stopService() {
lifecycleScope.launch {
delay(5000L)
try {
stopForeground(true)
isForeGroundService = false
stopSelf()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
让我们看看这个问题是否在我们的下一个构建中重现。
更新:)->这次没有与Context.startForegroundService()相关的问题,然后没有调用service . start前台()
之前/之后comparission - >
在- - - >
后- - - - - - >
我在Pixel 3和Android 11中遇到了一个问题,当我的服务运行得很短时,前台通知没有被取消。
在stopForeground() stopSelf()之前添加100ms的延迟似乎有所帮助。
人们在这里写道,stopprospect()应该在stopSelf()之前被调用。我不能确认,但我猜它不会费心去做。
public class AService extends Service {
@Override
public void onCreate() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(
getForegroundNotificationId(),
channelManager.buildBackgroundInfoNotification(getNotificationTitle(), getNotificationText()),
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
} else {
startForeground(getForegroundNotificationId(),
channelManager.buildBackgroundInfoNotification(getNotificationTitle(), getNotificationText())
);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground();
if (hasQueueMoreItems()) {
startWorkerThreads();
} else {
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
private class WorkerRunnable implements Runnable {
@Override
public void run() {
while (getItem() != null && !isLoopInterrupted) {
doSomething(getItem())
}
waitALittle();
stopForeground(true);
stopSelf();
}
private void waitALittle() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}