MQTT Creates Multiple connections when onCreate is called more than once

本小妞迷上赌 提交于 2020-01-15 10:02:05

问题


I am creating an instant messaging system using Paho Android MQTT Client. Its implementation works as expected, however I am facing these errors.

I call the Connection Class ( This also calls for the creation of the connection to the broker) in the onCreate of the MainActivity Class.

Now the problem is that, assuming I am on the MainActivity Class and I press back to move from the MainActivity Class to another activity, and I later come back to the MainActivity Class, another broker connection will be created. This will mean that anytime a single message is published, the client will receive the message twice.

MainActivity.java:

public class MainActivity extends AppCompatActivity {

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

    dbHelper = DatabaseManager.getInstance(context);
    //mRecyclerView = (RecyclerView) findViewById(R.id.history_recycler_view);

    connections = new Connections();
    connections.createConnectionForPublishing(context);

}


@Override
public void onDestroy() {
    super.onDestroy();
    System.out.println("LOG: Service destroyed");
}

}

Connection.java

public class Connection {

    public void createConnectionForPublishing (final Context context) {

        //Instantiate the mqtt android client class
        mqttAndroidClient = new MqttAndroidClient (context.getApplicationContext (), serverUri, clientId);


        mqttAndroidClient.setCallback (new MqttCallbackExtended () {

            @Override
            public void connectComplete(boolean reconnect, String serverURI) {
                if (reconnect) {
                    System.out.println ("Reconnected to : " + serverURI);
                } else {
                    System.out.println ("Connected to: " + serverURI);
                }
            }

            @Override
            public void connectionLost (Throwable cause) {
                System.out.println ("The Connection was lost.");
            }

            @Override
            public void messageArrived (String topic, final MqttMessage message) throws Exception {
                System.out.println ("Message received and Arrived");
            }

            @Override
            public void deliveryComplete (IMqttDeliveryToken token) {
                System.out.println("Message Delivered");
            }
        });

        final MqttConnectOptions mqttConnectOptions = new MqttConnectOptions (); 
        mqttConnectOptions.setMqttVersion (MqttConnectOptions.MQTT_VERSION_3_1_1);
        mqttConnectOptions.setAutomaticReconnect (true);
        mqttConnectOptions.setCleanSession (false);

        try {
            mqttAndroidClient.connect (mqttConnectOptions, null, new IMqttActionListener () {

                @Override
                public void onSuccess (IMqttToken asyncActionToken) {
                    System.out.println ("BROKER CONNECTED");

                    DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions ();
                    disconnectedBufferOptions.setBufferEnabled (true);
                    disconnectedBufferOptions.setBufferSize (100);
                    disconnectedBufferOptions.setPersistBuffer (false);
                    disconnectedBufferOptions.setDeleteOldestMessages (false);

                    //mqttAndroidClient.setBufferOpts (disconnectedBufferOptions);

                }

                @Override
                public void onFailure (IMqttToken asyncActionToken, Throwable exception) {
                    System.out.println ("Failed to connect to: " + serverUri);
                }
            });

        } catch (MqttException ex) {
            ex.printStackTrace ();
        }
    }

    // ...
}

I am new to MQTT, I would be glad if somebody can help. Thanks in advance


回答1:


Then if you don't want to establish the connection multiple times you'll have to make it as singleton to have only 1 instance of the connection class and one time connection established.

So your code will become:

MainActivity.java:

public class MainActivity extends Activity {

    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.chat_intera);

        Connection connection = Connection.getInstance (getApplicationContext ());
    }

    // ....
}

Connection.java

public class Connection {

    private       static Connection          connInst;
    private       static boolean             connected;

    private       static MqttAndroidClient   mqttAndroidClient;
    private       static IMqttActionListener mqttActionListener;
    private final static MqttConnectOptions  mqttConnectOptions = new MqttConnectOptions (); 
    static {
        mqttConnectOptions.setMqttVersion (MqttConnectOptions.MQTT_VERSION_3_1_1);
        mqttConnectOptions.setAutomaticReconnect (true);
        mqttConnectOptions.setCleanSession (false);
    }

    private Connection (Context context) {
        //Instantiate the mqtt android client class
        mqttAndroidClient = new MqttAndroidClient (context.getApplicationContext (), serverUri, clientId);

        mqttAndroidClient.setCallback (new MqttCallbackExtended () {

            @Override
            public void connectComplete (boolean reconnect, String serverURI) {
                connected = true;
                if (reconnect) {
                    System.out.println ("Reconnected to : " + serverURI);
                } else {
                    System.out.println ("Connected to: " + serverURI);
                }
            }

            @Override
            public void connectionLost (Throwable cause) {
                connected = false;
                System.out.println ("The Connection was lost.");
            }

            @Override
            public void messageArrived (String topic, final MqttMessage message) throws Exception {
                System.out.println ("Message received and Arrived");
            }

            @Override
            public void deliveryComplete (IMqttDeliveryToken token) {
                System.out.println("Message Delivered");
            }
        });

        mqttActionListener = new IMqttActionListener () {

            @Override
            public void onSuccess (IMqttToken asyncActionToken) {
                System.out.println ("BROKER CONNECTED");

                DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions ();
                disconnectedBufferOptions.setBufferEnabled (true);
                disconnectedBufferOptions.setBufferSize (100);
                disconnectedBufferOptions.setPersistBuffer (false);
                disconnectedBufferOptions.setDeleteOldestMessages (false);

                //mqttAndroidClient.setBufferOpts (disconnectedBufferOptions);

            }

            @Override
            public void onFailure (IMqttToken asyncActionToken, Throwable exception) {
                System.out.println ("Failed to connect to: " + serverUri);
            }
        });
    }

    public static Connection getInstance (Context context) {
        if (connInst == null) {
            connInst = new Connection (context);
        }
        createConnectionIfNeeded (context);

        return connInst;
    }

    private static void createConnectionIfNeeded () {
        if (connected) {
            return;
        }

        try {
            mqttAndroidClient.connect (mqttConnectOptions, null, mqttActionListener);

        } catch (MqttException ex) {
            ex.printStackTrace ();
        }
    }

    // ...
}



回答2:


I'm not sure but I think maybe a null check can help that

if (connection == null){
   connections = new Connections();
   connections.createConnectionForPublishing(context);
}



回答3:


I suggest that you set a flag using Android onPause()

https://developer.android.com/reference/android/app/Activity.html#onPause()

And then instead of using onCreate(), use onResume() to initiate your MQTT connection but check onPause() flag first.

You may also need to close the connection in onPause() or onDestroy(). Look at lifetime of an Android application/activity for more info.



来源:https://stackoverflow.com/questions/42101259/mqtt-creates-multiple-connections-when-oncreate-is-called-more-than-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!