I am developing an Android chat app which uses asmack library. What I observe is that the XMPP connection beocmes disconnected after a particular interval of time. ( This also varies from device to device )
I am runnning the connection code in a separate thread as instructed in the below link
Can't establish a new connection with aSmack 4.0.2
But I get the following exception
D/Reconnection Manager(23105): scheduleReconnect: calling tryToConnect
I/System.out(23105): default ping interval is :10
W/System.err(23105): org.jivesoftware.smack.SmackException$ConnectionException
W/System.err(23105): at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPConnection.java:436)
W/System.err(23105): at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:811)
W/System.err(23105): at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:396)
W/System.err(23105): at com.connectlinks.service.ChatService.connectToXmppServer(ChatService.java:309)
W/System.err(23105): at com.connectlinks.service.ChatService.access$0(ChatService.java:291)
W/System.err(23105): at com.connectlinks.service.ChatService$3.run(ChatService.java:280)
W/System.err(23105): at android.os.Handler.handleCallback(Handler.java:733)
W/System.err(23105): at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err(23105): at android.os.Looper.loop(Looper.java:136)
W/System.err(23105): at android.app.ActivityThread.main(ActivityThread.java:5586)
W/System.err(23105): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(23105): at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err(23105): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
W/System.err(23105): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
W/System.err(23105): at dalvik.system.NativeStart.main(Native Method)
Not sure where I am going wrong. I got to know from many of SO questions that connecting/reconecting in a separate thread works. But not happening for me...
The below is the code blocks which I am using
Below here I initially connect to the XMPP server and all good
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
.......
startXmppThread();
.......
}
the below code block where I am starting the XMPP thread
public void startXmppThread(){
isConnecting = true;
SmackAndroid.init(ChatService.this);
PingManager.setDefaultPingInterval(10);
SmackConfiguration.setDefaultPacketReplyTimeout(20000);
if(xmppThread == null){
xmppThread=new Thread(xmppRunnable,"connection thread");
xmppThread.start();
}
}
The XMPP runnable code
Runnable xmppRunnable = new Runnable() {
@Override
public void run() {
Log.d(TAG,"starting now thread :"+Thread.currentThread().getId()+" : "+Thread.currentThread().getName());
Looper.prepare();
try{
connectToXmppServer();
handler.post(mRunnableConnectionMonitor);
}catch (Exception e) {
//handler.removeCallbacks(mRunnableConnectionMonitor);
Log.d(TAG, "Trying to Reconnect from the run catch exception");
scheduleReconnect();
e.printStackTrace();
}
xyzz = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(android.os.Message msg) {
switch (msg.arg1) {
case 1:
Log.d(TAG, "Got Message to connect again");
try {
connectToXmppServer();
handler.post(mRunnableConnectionMonitor);
} catch (Exception e) {
//handler.removeCallbacks(mRunnableConnectionMonitor);
Log.d(TAG,"Trying to reconnect from the handleMessage case 1");
scheduleReconnect();
e.printStackTrace();
}
break;
case 2:
Log.d(TAG, "Got Message to disconnect");
handler.removeCallbacks(mRunnableConnectionMonitor);
try {
connection.disconnect();
Log.d(TAG, "succesfully disconnected");
}catch (Exception e) {
Log.d(TAG, "Exception while disconnecting");
e.printStackTrace();
}
break;
case 3:
Log.d(TAG,"Trying to reconnect from the handleMessage case 3");
scheduleReconnect();
handler.removeCallbacks(mRunnableConnectionMonitor);
break;
default:
break;
}
return false;
}
});
Looper.loop();
}
};
The code block which connects to the XMPP server
private void connectToXmppServer() throws Exception {
if(config ==null)
config = new ConnectionConfiguration(CHAT_SERVER_IP, 5222,host);
config.setSecurityMode(SecurityMode.disabled);
config.setSendPresence(true);
config.setRosterLoadedAtLogin(false);
if(connection == null)
connection = new XMPPTCPConnection(config);
if(mPingManager == null)
mPingManager = PingManager.getInstanceFor(connection);
mPingManager.unregisterPingFailedListener(mPingFailedListener);
mPingManager.registerPingFailedListener(mPingFailedListener);
System.out.println("default ping interval is :"+mPingManager.getPingInterval());
if(!connection.isConnected())
connection.connect();
if(!ConnectlinksApp.m_sharedHelper.getChatRegistration()){
String mobileID = ConnectlinksApp.m_sharedHelper.getMobileID();
Log.d(TAG, "trying to register with : "+mobileID);
AccountManager accountManager=AccountManager.getInstance(connection);
try{
accountManager.createAccount(mobileID, m_strUserPassword);
Log.d(TAG, "account created successfully"+mobileID);
}catch (Exception e) {
Log.d(TAG, "account already exist"+mobileID);
e.printStackTrace();
}
ConnectlinksApp.m_sharedHelper.setChatRegistration(true);
}
if(!connection.isAuthenticated()){
login();
}
}
The code block whicj reconnects to the XMPP server
protected void scheduleReconnect() {
if (mReconnectHandler == null) mReconnectHandler = new Handler();
mReconnectHandler.removeCallbacks(mReconnectRunnable);
Log.d("Schedule Reconnect","scheduleReconnect: scheduling reconnect in 10 seconds");
mReconnectHandler.postDelayed(mReconnectRunnable, 10000);
}
The runnable which reconnects
private final Runnable mReconnectRunnable = new Runnable() {
@Override
public void run() {
Log.d("Reconnection Manager","scheduleReconnect: calling tryToConnect");
try{
connectToXmppServer();
handler.post(mRunnableConnectionMonitor);
Log.d(TAG, "This shold be called");
}catch (Exception e) {
// handler.removeCallbacks(mRunnableConnectionMonitor);
e.printStackTrace();
scheduleReconnect();
}
}
};
I tried all possibilities but not able to arrive at a solution. Could anyone who has faced the same issue can help me please. Thanks for your time to read the long post.
*******************EDIT********************** The exception log is
10-23 19:48:50.866 I/System.out(15248): This is what I am looking for beginning
10-23 19:48:50.876 E/ERROR (15248): ConnectionException
10-23 19:48:50.876 E/ERROR (15248): org.jivesoftware.smack.SmackException$ConnectionException
10-23 19:48:50.876 E/ERROR (15248): at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPConnection.java:436)
10-23 19:48:50.876 E/ERROR (15248): at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:811)
10-23 19:48:50.876 E/ERROR (15248): at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:396)
10-23 19:48:50.876 E/ERROR (15248): at com.connectlinks.service.ChatService.connectToXmppServer(ChatService.java:314)
10-23 19:48:50.876 E/ERROR (15248): at com.connectlinks.service.ChatService.access$0(ChatService.java:293)
10-23 19:48:50.876 E/ERROR (15248): at com.connectlinks.service.ChatService$3.run(ChatService.java:281)
10-23 19:48:50.876 E/ERROR (15248): at android.os.Handler.handleCallback(Handler.java:733)
10-23 19:48:50.876 E/ERROR (15248): at android.os.Handler.dispatchMessage(Handler.java:95)
10-23 19:48:50.876 E/ERROR (15248): at android.os.Looper.loop(Looper.java:136)
10-23 19:48:50.876 E/ERROR (15248): at android.app.ActivityThread.main(ActivityThread.java:5586)
10-23 19:48:50.876 E/ERROR (15248): at java.lang.reflect.Method.invokeNative(Native Method)
10-23 19:48:50.876 E/ERROR (15248): at java.lang.reflect.Method.invoke(Method.java:515)
10-23 19:48:50.876 E/ERROR (15248): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
10-23 19:48:50.876 E/ERROR (15248): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
10-23 19:48:50.876 E/ERROR (15248): at dalvik.system.NativeStart.main(Native Method)
10-23 19:48:50.885 E/ERROR (15248): 54.215.XXX.YYY:5222 Exception: null
10-23 19:48:50.885 I/System.out(15248): This is what I am looking for end
*******************End of Exception Log *****************************
So it basically means it is not able to identify the chat server but it is up and running.
Is there any settings I need to do in Ejabberd server. Quite confused. Pls. help me.
The code which I used to get the exception is
System.out.println("This is what I am looking for beginning");
Log.e("ERROR", "ConnectionException", e);
for (int i = 0; i < e.getFailedAddresses().size(); i++) {
HostAddress element = e.getFailedAddresses().get(i);
Log.e("ERROR", element.getErrorMessage().toString());
}
System.out.println("This is what I am looking for end");
**********************EDIT*************************
Upon further investigation, I got to know that the connectToXmppServer method is in a Runnable.
Runnable xmppRunnable = new Runnable() {
@Override
public void run() {
.....
connectToXmppServer();
.....
}
}
So, changed the Runnable to a Thread like this
Thread xmppRunnable = new Thread(){
After this, the good news is though I am not able to solve the issue (which is the user goes offline in a few hours) I am getting the exception which states that the exception is NetworkOnMainThreadException
I/System.out(10663): NOT CONNECTED
I/System.out(10663): TRYING TO CONNECT
I/System.out(10663): SSmackThis is what I am looking for beginning
I/System.out(10663): SSmackYour localized messagenull
I/System.out(10663): SSmackYour Messagenull
E/ERROR (10663): SConnectionException
E/ERROR (10663): org.jivesoftware.smack.SmackException$ConnectionException
E/ERROR (10663): at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPConnection.java:436)
E/ERROR (10663): at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:811)
E/ERROR (10663): at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:396)
E/ERROR (10663): at com.connectlinks.service.ChatService.connectToXmppServer(ChatService.java:326)
E/ERROR (10663): at com.connectlinks.service.ChatService.access$0(ChatService.java:293)
E/ERROR (10663): at com.connectlinks.service.ChatService$3.run(ChatService.java:281)
E/ERROR (10663): at android.os.Handler.handleCallback(Handler.java:733)
E/ERROR (10663): at android.os.Handler.dispatchMessage(Handler.java:95)
E/ERROR (10663): at android.os.Looper.loop(Looper.java:136)
E/ERROR (10663): at android.app.ActivityThread.main(ActivityThread.java:5586)
E/ERROR (10663): at java.lang.reflect.Method.invokeNative(Native Method)
E/ERROR (10663): at java.lang.reflect.Method.invoke(Method.java:515)
E/ERROR (10663): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
E/ERROR (10663): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
E/ERROR (10663): at dalvik.system.NativeStart.main(Native Method)
I/System.out(10663): MYERRORorg.jivesoftware.smack.SmackException$ConnectionException
I/System.out(10663): SThis is what I am looking for middle
E/SSSERROR(10663): android.os.NetworkOnMainThreadException
I/System.out(10663): SSSERROR android.os.NetworkOnMainThreadException
E/SERROR (10663): 54.XXX.XXX.XXX:5222 Exception: null
I/System.out(10663): SERROR 54.XXX.XXX.XXX:5222 Exception: null
I/System.out(10663): SThis is what I am looking for end
Not sure why I am getting this exception though I am running it in a seperate thread. Any pointers would be very useful to me. I hope this SO question will benefit everyone facing the issue.