Я считаю, что преобразование в двоичное представление проще для понимания этой проблемы.
float f = 0.27f;
double d2 = (double) f;
double d3 = 0.27d;
System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(f)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d2)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d3)));
Вы можете видеть, что float расширяется до double, добавляя 0s к концу, но двойное представление 0.27 является «более точным», следовательно, проблема.
111110100010100011110101110001
11111111010001010001111010111000100000000000000000000000000000
11111111010001010001111010111000010100011110101110000101001000
Реализовали ли вы onDestroy()
? Если нет, то я считаю, что это может быть решением - и вы остановите свой Timer
или все, что вы используете для запуска службы в onDestroy()
.
Службу можно остановить, вызвав ее метод stopSelf () или вызвав Context.stopService ().
См. Эту ссылку для получения дополнительной информации.
Я уверен, что это не остановлено, потому что в моей базе данных я все еще получаю позиции GPS из эмулятора, когда у меня есть кнопка, чтобы остановить службу.
Вы, вероятно, не отменяете регистрацию своего LocationListener
.
У меня была такая же проблема. Я обнаружил, что если к сервису GoogleApiClient
подключено и все еще происходит обновление местоположения, stopService()
не имеет никакого эффекта, отрасль сервиса () не была вызвана. Чтобы устранить проблему, я создал функцию остановки службы определения местоположения в коде службы. Вызовите stopLocationService()
из действия, а затем вызовите stopService. Вот пример кода:
public class myLocationService extends Service{
...
public void stopLocationUpdates() {
LocationService.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);
mGoogleApiClient.disconnect();
}
...
}
В деятельности,
{
...
if(mService != null && isBound) {
mService.stopLocationUpdates();
doUnbindService();
stopService(new Intent(this, myLocationService.class));
}
...
}
Это очень распространенная ситуация, когда мне нужно остановить службу, прежде чем завершить процесс. В некоторых случаях недостаточно с stopService (намерением). Вы должны иметь в виду реализацию onDestroy () в моем сервисе. Пример:
public class MyIntentService extends IntentService {
// Defines and instantiates an object for handling status updates.
private BroadcastNotifier mBroadcaster = null;
private int progress = 0; //THIS IS MY COUNTER FOR EXAMPLE!!!
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
progress = 0;
int tiempo_disponible = intent.getIntExtra("minutos_disponible", 0);
if (mBroadcaster == null){
mBroadcaster = new BroadcastNotifier(this);
}
// Broadcasts an Intent indicating that processing has started.
mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_STARTED);
mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_RUNNING);
while (progress < tiempo_disponible) {
progress++;
try {
Log.i(Constants.TAG, "Procesing " + progress);
mBroadcaster.notifyProgress(progress);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Reports that the feed retrieval is complete.
mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_COMPLETE);
}
@Override
public void onDestroy() {
progress = 1000000; // WHITH THAT YOU FINISH THE CICLE IF tiempo_disponible NEVER IS MAYOR THAT 1000000, YOU CAN USE OTHER CONDITIONAL!!!!!!
super.onDestroy();
}
}
Таким образом, когда вы остановили службу с помощью метода stopService, вы также остановите счетчик процесса.
public void stopService(){
context.stopService(intent);
LocalBroadcastManager.getInstance(context).unregisterReceiver(responseReceiver);
responseReceiver = null;
intent = null;
}
Берегите себя! @yaircarreno
Возможно, вы создаете новое намерение каждый раз, когда вызываете службу остановки.
stopService(new Intent(GPSLoc.this, MyService.class));
возможно, попробуйте:
Intent intnet = new Intent(GPSLoc.this, MyService.class); // create el service
startService(intenet);
stopService(intent);
Если вы отслеживаете местоположение GPS, вы, вероятно, использовали GoogleApiClient
.
Концепция заключается в том, что Сервис НЕ ОСТАНОВИТСЯ,
, если экземпляр GoogleApiClient
все еще подключен к нему.
(Или любая другая проблема, которую нужно сначала уничтожить / незарегистрировать)
Итак, чтобы заставить ее работать, внедрите onDestroy()
в своем сервисе:
@Override
public void onDestroy()
{
// Unregistered or disconnect what you need to
// For example: mGoogleApiClient.disconnect();
super.onDestroy();
}
В моем случае stopService
вызывается с startService
почти одновременно, поэтому никакая служба не может быть остановлена. Попробуйте задержать stopService
на несколько секунд. :)
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.d(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
Для тех, кто хочет периодически отправлять запрос на сервер, это моё решение. Вы должны иметь это в своей деятельности или деятельности фрагмента
{
private static final Long UPDATE_LOCATION_TIME = 30 * 60 * 1000l; // 30 minute
private AlarmManager alarm;
private PendingIntent pIntent;
...
@Override
protected void onResume() {
super.onResume();
// Run background service in order to update users location
startUserLocationService();
Log.e(TAG, "onResume");
}
@Override
protected void onStop() {
super.onStop();
stopUserLocationService();
Log.e(TAG, "onStop");
}
private void startUserLocationService() {
Log.i(TAG, "Starting service...");
Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
pIntent = PendingIntent.getService(this, 0, intent, 0);
alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), UPDATE_LOCATION_TIME, pIntent);
}
private void stopUserLocationService() {
alarm.cancel(pIntent);
Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
stopService(intent);
}
}
Моя проблема решена путем удаления добавленных просмотров в WindowManager
ondestroy
public void onDestroy() {
isRunning = false;
super.onDestroy();
if (checkBox!=null) {
windowManager.removeView(getlayoutparm(fabsetting,fabrateus,fabexit,true));
windowManager.removeView(checkBox);
}
}
Я нашел, что лучший способ остановить сервис состоит в том, чтобы сделать саму остановку. Таким образом, Вы уверены, что это на самом деле остановит и сохранит целостность данных. Если Вы хотите сделать это от внешнего (действие), я обычно использую глобальный статический атрибут.
На пример (Kotlin), если я имею MyService
, MyActivity
и MyObject
Мой Объект
object MyObject{
abort = false
}
MyService
override fun onHandleIntent(intent: Intent?) {
startForeground(id,notification)
for (i in range){
if (MyObject.abort) break
// RUN SOME CODE HERE
}
stopForeground(true)
stopSelf()
}
MyActivity
fun startService() {
startForegroundService(Intent(this, OptimizationService::class.java))
}
fun stopService() {
MyObject.abort = true
}