Android 停止作为前台运行的服务的正确方法是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20857120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the proper way to stop a service running as foreground
提问by user1940676
I am trying to stop a service which is running as foreground service.
我正在尝试停止作为前台服务运行的服务。
The current issue is that when I call stopService()
the notification still stays.
当前的问题是,当我打电话时stopService()
,通知仍然存在。
So in my solution I have added a receiver which I am registering to inside the onCreate()
所以在我的解决方案中,我添加了一个接收器,我正在注册到 onCreate()
Inside the onReceive()
method I call stopforeground(true)
and it hides the notification.
And then stopself()
to stop the service.
在onReceive()
我调用的方法中stopforeground(true)
,它隐藏了通知。然后stopself()
停止服务。
Inside the onDestroy()
I unregistered the receiver.
在onDestroy()
我取消注册接收器的内部。
Is there a more proper way to handle this? because stopService() simply doesn't work.
有没有更合适的方法来处理这个问题?因为 stopService() 根本不起作用。
@Override
public void onDestroy(){
unregisterReceiver(receiver);
super.onDestroy();
}
回答by Ilya Gazman
From your activity call startService(intent)
and pass it some data that will represent a key to stop the service.
从您的活动调用中startService(intent)
传递一些数据,这些数据将代表停止服务的键。
From your service call stopForeground(true)
and then stopSelf()
right after it.
从您的服务电话开始stopForeground(true)
,然后stopSelf()
紧随其后。
回答by Elad
to start and stop a foreground service from an activity use :
从活动使用开始和停止前台服务:
//start
Intent startIntent = new Intent(MainActivity.this, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(startIntent);
//stop
Intent stopIntent = new Intent(MainActivity.this, ForegroundService.class);
stopIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(stopIntent);
in your foreground service - use (at least) this code:
在您的前台服务中 - 使用(至少)此代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Start Foreground Intent ");
// your start service code
}
else if (intent.getAction().equals( Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
//your end servce code
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
回答by Ahmed Shahid
As stated here: https://developer.android.com/guide/components/services#Stopping
如此处所述:https: //developer.android.com/guide/components/services#Stopping
A started service must manage its own lifecycle. That is, the system doesn't stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand()returns. The service must stop itself by calling stopSelf(), or another component can stop it by calling stopService().
启动的服务必须管理自己的生命周期。也就是说,系统不会停止或销毁服务,除非它必须恢复系统内存并且服务在onStartCommand()返回后继续运行。服务必须通过调用stopSelf()来停止它自己,或者另一个组件可以通过调用stopService()来停止它。
Once requested to stop with stopSelf() or stopService(), the system destroys the service as soon as possible.
一旦使用stopSelf() 或 stopService()请求停止,系统会尽快销毁服务。
So you can call stopService() from the activity that you used to call startService(). I have done that right here:
因此,您可以从用于调用 startService() 的活动中调用 stopService()。我在这里做到了:
start_button.setOnClickListener {
applicationContext.startForegroundService(Intent(this, ServiceTest::class.java))
}
stop_button.setOnClickListener {
applicationContext.stopService(Intent(this, ServiceTest::class.java))
}
I created two buttons to start and stop the service and it works.
我创建了两个按钮来启动和停止服务并且它可以工作。
回答by Nerius Jok
In addition to other answers i ended with this snippet using android oreo and laters to stop job services.
除了其他答案之外,我还使用 android oreo 和更高版本来停止工作服务。
Intent intent = new Intent(getApplicationContext(), LocationService.class);
intent.setAction(status);
ContextCompat.startForegroundService(getApplicationContext(), intent);
And in service
并在服役
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
startForeground(121, notification);
if (intent.getAction().equals("StopService")) {
stopForeground(true);
stopSelf();
}
startForeground() is mandatory unless app will crash without calling it
startForeground() 是强制性的,除非应用程序在没有调用它的情况下崩溃
The new Context.startForegroundService() method starts a foreground service. The system allows apps to call Context.startForegroundService() even while the app is in the background. However, the app must call that service's startForeground() method within five seconds after the service is created.
新的 Context.startForegroundService() 方法启动前台服务。即使应用程序在后台,系统也允许应用程序调用 Context.startForegroundService()。但是,应用程序必须在服务创建后五秒内调用该服务的 startForeground() 方法。
https://developer.android.com/about/versions/oreo/android-8.0-changes.html
https://developer.android.com/about/versions/oreo/android-8.0-changes.html
回答by beginner
From Activity
从活动
stopService(new Intent(this, ForegroundService.class));
From Service itself
从服务本身
stopForeground(true);
stopSelf()
回答by LincyTonita
If you want to stop service and then update notification, you can first call stopSelf() and then notify(). stopForeground(false) makes the notification cancelable.
如果要停止服务然后更新通知,可以先调用stopSelf(),然后再调用notify()。stopForeground(false) 使通知可取消。
private final BroadcastReceiver myBgWorkCompleteReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
stopSelf();
notificationLayoutExpanded.setTextViewText(R.id.file_download_notify_download_percentage, "Background work completed");
manager.notify(mNotificationId, notification);
stopForeground(false);
}
};
public void onDestroy() {
super.onDestroy();
// cancel any running threads here
LocalBroadcastManager.getInstance(this).unregisterReceiver(myBgWorkCompleteReceiver);
}
回答by D Dimitrov
I have found the best way to stop a service is to make stop itself. This way you are sure it actually will stop and preserve data integrity. If you want to do it from outside (activity) I usually use a global static attribute.
我发现停止服务的最好方法是让停止本身。这样您就可以确定它实际上会停止并保持数据完整性。如果您想从外部(活动)执行此操作,我通常使用全局静态属性。
Check my answer here : https://stackoverflow.com/a/57833370/7795547
在这里检查我的答案:https: //stackoverflow.com/a/57833370/7795547