Как остановить сервис самостоятельно?
Я запускаю службу в действии, а затем хочу, чтобы служба через некоторое время остановилась.
Я вызвал stopSelf() в сервисе, но он не работает.
Как заставить сервис остановиться сам?
10 ответов
Говоря "не работает", я думаю, вы имеете в виду, что onDestroy()
-метод службы не вызывается.
У меня была такая же проблема, потому что я связал некоторое ServiceConnection с самим Сервисом, используя флаг BIND_AUTO_CREATE. Это приводит к тому, что служба остается активной до тех пор, пока не будет разорвано каждое соединение.
После того, как я перешел на использование без флага (ноль), у меня не возникло проблем с уничтожением службы самостоятельно (stopSelf()
).
Пример кода:
final Context appContext = context.getApplicationContext();
final Intent intent = new Intent(appContext, MusicService.class);
appContext.startService(intent);
ServiceConnection connection = new ServiceConnection() {
// ...
};
appContext.bindService(intent, connection, 0);
Убить сервис (не процесс):
this.stopSelf();
Надеюсь, что это помогло.
По телефону stopSelf()
Служба останавливается.
Пожалуйста, убедитесь, что ни один поток не работает в фоновом режиме, что заставляет вас чувствовать, что служба не остановлена.
Добавить печатные заявления в вашей теме.
Надеюсь это поможет.
Так как вы не опубликовали свой код, я не могу точно знать, что вы делаете, но вы должны объявить, ЧТО вы останавливаете:
this.stopSelf();
как в:
public class BatchUploadGpsData extends Service {
@Override
public void onCreate() {
Log.d("testingStopSelf", "here i am, rockin like a hurricane. onCreate service");
this.stopSelf();
}
Если под "не работает" вы имеете в виду, что процесс не будет убит, тогда работает Android. System.exit(0)
или же Process.killProcess(Process.myPid())
убьет ваш процесс. Но это не Android-способ делать вещи.
НТН
Чтобы позволить вашему сервису остановить себя.. создайте BroadcastReceiver
класс.. К вашим услугам вызов вашего приемника, как это..
В сервисе
sendBroadcast(new Intent("MyReceiver"));
В трансляции приемник
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.stopService(new Intent(context,NotificationService.class));
}
}
Файл манифеста
<receiver
android:name="MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyReceiver"/>
</intent-filter>
</receiver>
Я знаю, что это старый вопрос, но в моем случае (плавающее окно как услуга) мне пришлось сначала удалить представление, а затем позвонить stopSelf()
.
windowManager.removeView(floatingView);
stopSelf();
Используйте stopSelf(), чтобы остановить службу от самого себя.
Если вы используете отдельный Thread
к вашим услугам, после прекращения обслуживания по телефону stopSelf()
или же stopService()
Thread
продолжает бежать. если ты хочешь остановиться Thread
ты должен позвонить Thread.interrupted()
в Thread
(это может привести к Exception
если Thread
спит)
Я просто столкнулся с той же проблемой. В моем случае у меня есть менеджер одноэлементного сервиса, который я использую для связи с сервисом. В диспетчере сервис запускается так:
context.bindService(new Intent(context, MyService.class), serviceConnection, Context.BIND_AUTO_CREATE);
Удалив Context.BIND_AUTO_CREATE в соответствии с предложением Алика Эльзина, я смог остановить службу, используя this.stopSelf(), и при этом вызывать onDestroy(). Эта проблема в том, что после этого я не смог перезапустить сервис из менеджера с помощью команды выше.
Наконец, я исправил это с помощью обратного вызова из службы, который говорит менеджеру остановить службу. Таким образом, менеджер всегда отвечает за запуск / остановку службы, и все, кажется, работает нормально. Я не знаю, есть ли какие-либо противопоказания в этом.
Код действительно прост. Создайте обратный вызов в сервисе и установите его в менеджере, например, в своем классе соединения:
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
myService = ((MyService.LocalBinder)service).getService();
myService.setCallback(new MyService.MyServiceCallback() {
@Override
public void onStop() {
stopService();
}
});
}
public void onServiceDisconnected(ComponentName className) {
myService = null;
}
};
и остановить сервис:
public void stopService()
{
if(mServiceConnection != null){
try {
mContext.unbindService(mServiceConnection);
} catch (Exception e) {}
}
mContext.stopService(new Intent(mContext, BleDiscoveryService.class));
}
В сервисе просто вызовите myCallback.onStop(), когда вам нужно остановить его.
Еще один грязный хак, не упомянутый здесь, это выбросить исключение типа NPE. Однажды мне нужно было остановить InputMethodService, и этот хак был полезен.