2016-08-02 13 views
1

Ich versuche, die grundlegende Eclipse Paho MQTT-Client-Version 1.1.0 zu einer CloudAMQP RabbitMQ-Instanz zu verbinden, ein Thema abonnieren und Nachrichten (die ich aus dem Web senden) Admin-Konsole).Paho Android Client löscht Verbindung, wenn eine Nachricht angezeigt wird

Es funktioniert gut, wenn die Anwendung alle Nachrichtennutzlasten an die Protokollausgabe sendet.

Wenn die Anwendung die Nachricht zu einem TextView hinzufügt, wird die Nachricht angezeigt, aber die Verbindung wird sofort unterbrochen und keine weitere Nachricht empfangen.

Das vollständige Projekt ist verfügbar unter GitHub. Ein einfaches Beispiel ist unten.

Es gibt einen Service-basierten MQTT-Paho-Client, aber ich dachte, dass der Basis-Client für sehr einfache Anwendungen Nachrichten in der Android-App-Benutzeroberfläche empfangen und anzeigen kann.

... 

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; 
import org.eclipse.paho.client.mqttv3.MqttCallback; 
import org.eclipse.paho.client.mqttv3.MqttClient; 
import org.eclipse.paho.client.mqttv3.MqttClientPersistence; 
import org.eclipse.paho.client.mqttv3.MqttConnectOptions; 
import org.eclipse.paho.client.mqttv3.MqttException; 
import org.eclipse.paho.client.mqttv3.MqttMessage; 
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; 

public class MainActivity extends AppCompatActivity implements MqttCallback { 

    private static final String TAG = "main"; 
    private Connection connection; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     configureUI(); 
    } 

    private Button buttonConnect; 
    private TextView messageWindow; 


    private void configureUI() { 
     buttonConnect = (Button) findViewById(R.id.buttonConnect); 
     messageWindow = (TextView) findViewById(R.id.messageWindow); 

     buttonConnect.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       String s = "***"; 
       String d = "test"; 
       String u = "***"; 
       String p = "***"; 

       if (connection != null && connection.isConnected()) { 
        connection.disconnect(); 
        connection = null; 
        messageWindow.setText(String.format("Disconnected from server %s", 
          new Object[]{s})); 
        return; 
       } 

       messageWindow.setText(String.format("Connecting to server %s as user %s", 
         new Object[]{s, u})); 

       connection = new Connection(MainActivity.this, MainActivity.this, s, u, p); 
       connection.connect(); 

       if (connection.isConnected()) { 
        messageWindow.append("\n\n"); 
        messageWindow.append(String.format("Connected, listening for messages from topic %s", 
          new Object[]{d})); 
        connection.subscribe(d); 
       } 
      } 
     }); 
    } 

    @Override 
    public void connectionLost(Throwable cause) { 
     Log.e(TAG, "connectionLost" + cause.getMessage()); 
    } 

    @Override 
    public void messageArrived(String topic, MqttMessage message) throws Exception { 
     String msg = new String(message.getPayload()); 
     Log.i(TAG, "Message Arrived: " + msg); 
     // messageWindow.append(msg); 
    } 

    @Override 
    public void deliveryComplete(IMqttDeliveryToken token) { 
     Log.i(TAG, "Delivery Complete!"); 
    } 

    class Connection { 
     private static final String TAG = "conn"; 
     private static final String protocol = "tcp://"; 
     private static final int port = 1883; 
     private static final int version = MqttConnectOptions.MQTT_VERSION_3_1_1; 
     private static final int keepAliveSeconds = 20 * 60; 

     private final Context context; 
     private MqttClient client; 

     private final String server; 
     private final String user; 
     private final String pass; 

     private final MqttConnectOptions options = new MqttConnectOptions(); 

     public Connection(Context ctx, MqttCallback mqttCallback, String server, String user, String pass) { 
      this.context = ctx; 
      this.server = server; 
      this.user = user; 
      this.pass = pass; 

      MqttClientPersistence memPer = new MemoryPersistence(); 
      try { 
       String url = protocol + server + ":" + port; 
       client = new MqttClient(url, MqttClient.generateClientId(), memPer); 
       client.setCallback(mqttCallback); 
      } catch (MqttException e) { 
       e.printStackTrace(); 
      } 

      options.setUserName(user + ":" + user); 
      options.setPassword(pass.toCharArray()); 
      options.setMqttVersion(version); 
      options.setKeepAliveInterval(keepAliveSeconds); 
     } 

     void connect() { 
      Log.i(TAG, "buttonConnect"); 
      try { 
       client.connect(options); 
      } catch (MqttException ex) { 
       Log.e(TAG, "Connection attempt failed with reason code = " + ex.getReasonCode() + ":" + ex.getCause()); 
      } 
     } 

     public boolean isConnected() { 
      return client.isConnected(); 
     } 

     public void disconnect() { 
      try { 
       client.disconnect(); 
      } catch (MqttException e) { 
       Log.e(TAG, "Disconnect failed with reason code = " + e.getReasonCode()); 
      } 
     } 

     void subscribe(String dest) { 
      try { 
       client.subscribe(dest); 
      } catch (MqttException e) { 
       Log.e(TAG, "Subscribe failed with reason code = " + e.getReasonCode()); 
      } 
     } 
    } 
} 
+0

„die Verbindung empfangen wird, unmittelbar nachdem die Meldung angezeigt wurde“ Sie „die Verbindung unterbrochen wird sofort ...“ bedeuten Sie – hardillb

+0

@hardillb ich es fixiert, vielen Dank für bemerken! – mjn

Antwort

2

Ich würde vermuten, dies liegt daran, dass Sie versuchen, die TextView von einem nicht UI-Thread zu aktualisieren.

Versuchen Sie, die messageWindow.append(msg); in einem runOnUiThread Anruf einzuwickeln.

public void messageArrived(String topic, MqttMessage message) throws Exception { 
    String msg = new String(message.getPayload()); 
    Log.i(TAG, "Message Arrived: " + msg); 
    runOnUiThread(new Runnable(){ 
     public void run() { 
      messageWindow.append(msg); 
     } 
    }); 
} 
+1

Das hat es gelöst, vielen Dank! (Ich dachte, dass das Verschieben der gesamten Verbindung zu einer AsyncTask helfen könnte) – mjn

+0

Es funktioniert, dank Ihnen zwei –

Verwandte Themen