2015-07-19 11 views
6

ich ein Begrüßungsbildschirm Fragment haben, die Veranstaltung Bus registriert ist:Ereignis Bus Fragment Unregister

@Override 
public void onStart() { 
    super.onStart(); 
    EventBus.getDefault().register(this); 
} 

@Override 
public void onStop() { 
    EventBus.getDefault().unregister(this); 
    super.onStop(); 
} 

Wenn der Bildschirm autolock (oder jedes andere Ereignis, das OnStop nennen könnte), geht der Behälter Aktivität OnStop und die Fragment ist nicht mehr in der Lage, das (Netzwerk-) Ereignis zu empfangen. Ich denke über Verschieben "Unregister" Logik zu OnDestroy Methode. Ist es eine gute Idee?

Antwort

10

Sie können die Ereignis Busereignissen zu onStart() und onStop(), aber Sie sollten wissen, bewegen, dass bestimmte Methoden nicht nach onSaveInstanceState() aufgerufen werden kann (zum Beispiel ein DialogFragment entlassen Sie stürzt aus).

Also während dieses Beispiel für Otto war, wechselte ich es zu EventBus, und ich persönlich habe einen Wrapper, der Ereignisse speichert, während die Anwendung pausiert ist.

public enum SingletonBus { 
    INSTANCE; 

    private static String TAG = SingletonBus.class.getSimpleName(); 

    private final Vector<Object> eventQueueBuffer = new Vector<>(); 

    private boolean paused; 

    public <T> void post(final T event) { 
      if (paused) { 
       eventQueueBuffer.add(event); 
      } else { 
       EventBus.getDefault().post(event); 
      } 
    } 

    public <T> void register(T subscriber) { 
     EventBus.getDefault().register(subscriber); 
    } 

    public <T> void unregister(T subscriber) { 
     EventBus.getDefault().unregister(subscriber); 
    } 

    public boolean isPaused() { 
     return paused; 
    } 

    public void setPaused(boolean paused) { 
     this.paused = paused; 
     if (!paused) { 
      Iterator<Object> eventIterator = eventQueueBuffer.iterator(); 
      while (eventIterator.hasNext()) { 
       Object event = eventIterator.next(); 
       post(event); 
       eventIterator.remove(); 
      } 
     } 
    } 
} 

Dann wird in einem BaseActivity der Art,

public class BaseActivity extends AppCompatActivity { 
    @Override 
    public void onPostResume() { 
      super.onPostResume(); 
      SingletonBus.INSTANCE.setPaused(false); 
    } 

    @Override 
    public void onPause() { 
      SingletonBus.INSTANCE.setPaused(true); 
      super.onPause(); 
    } 
} 
+0

Schön! Sprechen Sie über IllegalStateException für die Übertragung von Fragmenttransaktionen innerhalb von Lebenszyklusmethoden? – Jumpa

+1

Ja. Das ist eine totale Schlampe, ich war überrascht, als ich hineingerannt bin. So erlaube ich die Übertragung von Ereignissen nur, wenn die App nicht pausiert ist. – EpicPandaForce

+0

Das liegt daran, dass das System Ihren Prozess nach 'onSaveInstanceState()' brutal beenden kann, so dass Sie die gerade begangene Transaktion verlieren könnten. Btw netter Code, aber warum 'Vector'? –

2

ich ein ähnliches Problem hatte vor kurzem. Zuerst habe ich Otto benutzt und bin dann zum EventBus von greenrobot gewechselt. Mit EventBus können Sie Ihre Objekte sticky registrieren. EventBus.getDefault().registerSticky(this) Das heißt, dieses Objekt erhält automatisch jedes klebrige Ereignis, auf das es nach der Registrierung wartet. Diese Ereignisse müssen dann als klebrig gekennzeichnet werden. (EventBus.getDefault().postSticky(event))

In Erwägung ziehen, die klebrigen Ereignisse zu entfernen, wenn Sie sie nicht mehr benötigen (EventBus.getDefault().removeSticky(Event.class)). Wenn Sie dieses Ereignis nur einmal erhalten möchten, sollten Sie es entfernen. Vielleicht könnte dieser Ansatz Ihren Bedürfnissen entsprechen.