Too many Smack threads get created

Am using the Smack demo application as reference and adding chat functionality to my Android app (right now the chat app is standalone).

My setup is

  1. Android client - Smack version is 4.1.0. My app gradle dependencies section looks like this
dependencies {
    compile 'com.android.support:appcompat-v7:+'
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'org.igniterealtime.smack:smack-android-extensions:4.1.0'
    compile 'org.igniterealtime.smack:smack-tcp:4.1.0'
}
  1. Server - openfire 3.10.0 server on my local host (Ubuntu 14.04) for testing.

  2. Another client - Spark 2.7.0 as the other end with which my chat app exchanges messages.

Thanks to the demo source code, was able to get the basic text exchange working between my Android app and Spark. However, every time I press home key and then launch the app again, there are additional Smack threads that I can see in the debugger section in Android studio. The new threads keeps increasing every time I launch the app.

This is screen shot of the threads the first time the application is launched

After back key or home is pressed, the threads look like this

On launching again, the threads section looks like this. However, the chat functionality continues to work properly.

Additional Smack threads (25-Packet Reader, 26-Ping, 27-Incoming Processor, 28-Single Threaded executor, 29-Remove Callbacks) can be seen.

My ChatManagerListener and ChatMessageListener look like this

//ChatManager listener
    @Override
    public void chatCreated(Chat chat, boolean createdLocally) {
        Log.d(TAG, "New chat created(local: " + createdLocally + ")");
        if(!createdLocally)
            chat.addMessageListener(this);
    }     //ChatMessage listener
    @Override
    public void processMessage(Chat chat, Message message) {
        Log.d(TAG, "Process message");
        if (message.getType() == Message.Type.chat || message.getType() == Message.Type.normal) {
            String msg = message.getBody();
            if(msg != null) {
                sendMessageIntent(message);
            }
        }
    }

I do the following when activity’s onStop is called (all the Smack calls are made via a looper thread create in a service).

  1. Remove the chat listener

  2. Disconnect the session

Verified through logs that disconnect indeed happens and also the user (from the app) shows offline in Spark.

What am I doing wrong in closing the connection? Any pointers please?

Are you still holding a (strong) reference to the connection after you disconnect?

I’d also recommend re-using existing connection instances as long as possible, i.e. as long as the connection parameters don’t change.

Thanks Flow for the tip. Using weak reference did the trick. Had a hard reference to the connection which was causing this problem. Created a WeakHashMap where I store the original connection and then use a global hard reference to the item in the WeakHashMap. Once the session is not required (after the graceful disconnection is done), I’m removing the hard reference.

I’d usually recommend simply nulling the strong reference over using a, typically more complex, weak reference.

I am nulling the strong reference. The strong reference points to the WeakHashMap. Is there a better way?

null the strong reference to the not longer used XMPPConnection

Was doing it earlier. But that didn’t solve the problem. Hence tried the weak reference method.