Alte Services Feuern wieder


#1

Moinsen.

Ich grübel seit gestern Abend an einen Problem mit meinem Service.
Ich starte einen Service in Activity A und stoppe diesen wieder.
Dann gehe ich zu Activity B und starte den selben Service und stoppe ihn wieder.
Öffne wieder Activity A starte wieder.

Was passiert ist folgendes:
In A feuert der Service so wie es soll (zB. einmal pro Sekunde).
Ich schalte den Service aus und er feuert nicht weiter.
So weit perfekt.

In B starte ich den Service und nun feuert Aber der Service von A UND B,
jeweils gleichzeitig. Entsprechend wird das Signal auch doppelt verarbeitet
(was bei einem Zähler ungünstig ist, da bei einer Sekunde zwei gezählt werden).
Ich stoppe den Service wieder und er schweigt (von A und B).

Jetzt gehe ich zu Activity A und starte den Servive.
Es wird zeitgleich von A, B und A gefeuert.

Natürlich soll jeweils nur einmal gefeuert werden!
Was mache ich falsch?**
Wie muss ich es programmieren, dass es nur einmal feuert???**

Jetzt der Quellcode dazu:
Aufruf des Services:

			Bundle extras = new Bundle();
			extras.putInt("unitOfTime", 1000);
			intent.putExtra("values", extras);
			startService(intent);```

Stoppen des Services:
```		stopService(new Intent(this, BottleAnimation.class));```

der Service:
```package com.name.service;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class BottleAnimation extends Service {

	private static final String TAG = "BottleAnimation";
	public static final String ACTION_BROADCAST = "com.name.service.BOTTLEANIMATION";
	private SignalerBinder mBinder = new SignalerBinder();	
	private Timer mTimer;
	private int unitOfTime;
	
	public class SignalerBinder extends Binder {
		public SignalerBinder(){
		}
	}
	@Override
	public void onCreate() {
		super.onCreate();
		mTimer = new Timer();
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		unitOfTime = intent.getBundleExtra("values").getInt("unitOfTime");
		mTimer.schedule(mTimerTask, unitOfTime, unitOfTime);		
		return super.onStartCommand(intent, flags, startId);		
	}
	private TimerTask mTimerTask = new TimerTask() {		
		@Override
		public void run() {	
			final Intent broadcastIntent = new Intent(ACTION_BROADCAST);
			getApplicationContext().sendBroadcast(broadcastIntent);
		}
	};
	
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
		mTimer.cancel();
	}
}```

Übrigens, beim Wechsel von einer Activity zur anderen verabschiede ich mich jeweils mit einem finish() (was nichts hilft um den alten Service los zu werden).
Und, hier vermute ich den anderen Teil des Problems, ich arbeite in allen Activities mit der selben Variable (aus einer Singleton-Klasse). Diese Variable wird bei jedem ServiceSignal in jeder Activity weitergezählt und zählt entsprechen zweimal, dreimal, .. so schnell. Hier werde ich ansetzen und eine Umgehung versuchen.

#2

(was nichts hilft um den alten Service los zu werden).

Natürlich nicht. Der Service ist entkoppelt von der Activity. Gib einmal Log-Ausgaben im onDestroy deines Services aus. Möglicherweise ist er noch nicht beendet bevor Activity B den startService-Intent wegschickt. Dann würde die alte Instanz am Leben bleiben. onStartCommand würde allerdings trotzdem ausgeführt weswegen ein neuer Timer-Thread angelegt wird. Diese zwei schicken dann brav ihre Nachrichten weiterhin im Intervall.


#3

So sieht es aus.

Im Moment versuche ich die Zählerlogik (onReseive) in meine Singletonklasse auszulagern.
Nur von dort starte ich dann den Service und lasse alle Berechnungen durchführen.
Gleichzeitig (so meine Logik) müsste ich in der aktuellen Activity mit onReceive ebenfalls das Signal abfangen können und auf die Werte aus der Singleton zugreifen können.
Dies hat auch den Vorteil, dass die Logik nur in nur einer Klasse steckt und sich nicht in den Activities wiederholt.

Ich melde mich, wenn ich ein Ergebnis habe.
(oder nicht weiter komme)


#4

Nun habe ich **eine neue Singletonklasse erstellt **ohne extends Application oder extrends Activity (siehe http://forum.byte-welt.net/threads/10279-NPE-bei-startService(intent)) und das ist gut so.

Darin befindet sich die Kalkulation, welche im onReceive() steckt.

Aber ein wesentlicher Punkt zur Behebung meines Problems war, dass ich
getApplicationContext().unregisterReceiver(mReceiver);
direkt nach Buttonklick zum wechseln der Activity setze.

:lol: