2015-07-19 17 views
5

Ich benutze Otto, um eine Buddyliste zu aktualisieren, wenn ein Freund debuddies mich. Ich habe Probleme mit der Aktualisierung der Benutzeroberfläche von einem Nicht-Haupt-Thread, also habe ich das Problem untersucht und 'gelöst' mit dieser post. Der Code, den sie verwenden, ist dies:Mit Otto einen Listenadapter von einem GcmListenerService aktualisieren

public class BusProvider extends Bus{ 

public static final String LOG_TAG = BusProvider.class.getSimpleName(); 

private final Handler mainThread = new Handler(Looper.getMainLooper()); 
private static Bus mInstance; 

public static synchronized Bus getInstance() { 
    if (mInstance == null) { 
     mInstance = new Bus(); 
    } 
    return mInstance; 
} 

@Override 
public void post(final Object event) { 
    if (Looper.myLooper() == Looper.getMainLooper()) { 
     Log.d(LOG_TAG, "Posting event using super!"); 
     super.post(event); 
    } else { 
     mainThread.post(new Runnable() { 
      @Override 
      public void run() { 
       Log.d(LOG_TAG, "Posting event using AndroidBus!"); 
       BusProvider.super.post(event); 
      } 
     }); 

    } 
} 

}

ich die Post wie diese machen:

final Bus bus = BusProvider.getInstance(); 
Log.d(LOG_TAG, "Attempting to post from LBGcmListenerService!"); 
bus.post(new BuddiesEvent()); 

im Wesentlichen ein Singleton Bus machen und durch die Entsendung, um sicherzustellen, dass es auf der Haupt ist Faden. Allerdings kann ich diesen Code nicht zum Funktionieren bringen. Ich instanziierte stattdessen den Handler in der Klasse, von der aus ich posten konnte:

final Bus bus = BusProvider.getInstance(); 
Handler handler = new Handler(Looper.getMainLooper()); 
handler.post(new Runnable() { 
     @Override 
     public void run() { 
     bus.post(new BuddiesEvent()); 
     } 
); 

Das funktioniert super. Aber ich möchte kein Handler-Objekt vor jedem Beitrag machen müssen. Ich weiß nicht, ob das ein Java-Problem oder ein Android-Problem ist, aber ich würde mich freuen, wenn mir jemand helfen könnte herauszufinden, wie man die Singleton-Klasse dazu bringt, dieses Problem zu lösen. Vielen Dank!

Feste: Setzen Sie den richtigen Code hier:

public class BusProvider extends Bus{ 

public static final String LOG_TAG = BusProvider.class.getSimpleName(); 

private final Handler mainThread = new Handler(Looper.getMainLooper()); 
private static BusProvider mInstance; 

public static synchronized BusProvider getInstance() { 
    if (mInstance == null) { 
     mInstance = new BusProvider(); 
    } 
    return mInstance; 
} 

@Override 
public void post(final Object event) { 
    if (Looper.myLooper() == Looper.getMainLooper()) { 
     Log.d(LOG_TAG, "Posting event using super!"); 
     super.post(event); 
    } else { 
     mainThread.post(new Runnable() { 
      @Override 
      public void run() { 
       Log.d(LOG_TAG, "Posting event using AndroidBus!"); 
       BusProvider.super.post(event); 
      } 
     }); 

    } 
} 

}

+0

Was ist das Problem mit der 'AndroidBus' Klasse? –

+0

Wenn ich die AndroidBus-Klasse verwende und bus.post auf meiner Bus-Instanz anrufe (die getInstance-Methode wird im obigen Code nicht angezeigt), erhalte ich die Fehlermeldung, dass "bus 'default" von einem Nicht-Hauptthread-Nullpunkt aus aufgerufen wurde ". Wenn ich den Handler in der Klasse instanziiere, die das Ereignis postet, wie das zweite Bit oben, funktioniert alles gut. @Gil, ** Wenn Sie die AndroidBus-Klasse zum Arbeiten nutzen können, indem Sie von einem Dienst anstatt von einer Aktivität posten, würde mich das interessieren! ** – Brandon

+0

Der Code sieht gut aus. Die einzige mögliche Erklärung, die ich mir vorstellen kann, ist der Looper des Threads. Looper.myLooper() gibt also null zurück, wenn der Bus schreibt (die Super-Klasse). Kannst du vielleicht überprüfen, welche dieser beiden, super.post (event) oder AndroidBus.super.post (event), fehlschlägt? (einige Logs kurz vor den Anrufen) –

Antwort

2

Ja, ich es herausgefunden. Die Antwort hier war nichts Geheimnisvolles. In meiner Singleton-Klasse erstellte ich ein Bus-Objekt und übergab es als Instanz. Ich habe keinen BusProvider gemacht. Daher rief ich beim Aufruf von post nicht die Methode BusProvider override auf, sondern die Bus-Methode, die in meinem Fall nicht "threadsicher" war. Nachdem ich den Code geändert habe, um diese Anerkennung widerzuspiegeln, funktionierte es großartig!