在与 Smack 4.2 重新连接后发送离线消息时,经过身份验证的侦听器出现异常

Posted

技术标签:

【中文标题】在与 Smack 4.2 重新连接后发送离线消息时,经过身份验证的侦听器出现异常【英文标题】:Exception in authenticated listener while Sending offline message after re connection with Smack 4.2 【发布时间】:2018-02-03 18:57:06 【问题描述】:

假设用户在聊天时失去了连接,但他发送了一些消息。重连成功后,聊天应用需要发送未发送的消息。 我使用此代码发送 Smack Connection Configuration 中配置的消息

private void sendMessage(String body, String toJid) throws XmppStringprepException 
    EntityBareJid jid = null;
    try 
        jid = JidCreate.entityBareFrom("monim@blah.im");
     catch (XmppStringprepException e) 
        e.printStackTrace();
    
    ChatManager chatManager = ChatManager.getInstanceFor(connection);
    Chat chat = chatManager.chatWith(jid);
    try 
        Message message = new Message(jid, Message.Type.chat);
        message.setBody(body);
        chat.send(message);
    catch (SmackException.NotConnectedException | InterruptedException e) 
        e.printStackTrace();
    

这个是从 Messages 活动调用 sendMessage() 方法

private void sendMessage(String message, String receiverJid) 

    if (SmackConnectionService.getConnectionState().equals(SmackConnection.ConnectionState.CONNECTED)) 

            Intent intent1 = new Intent(SmackConnectionService.SEND_MESSAGE);
            intent1.putExtra(SmackConnectionService.BUNDLE_MESSAGE_BODY, message);
            intent1.putExtra(SmackConnectionService.BUNDLE_TO, receiverJid);
            DefaultMessagesActivity.this.sendBroadcast(intent1);
     else 
        saveInDatabases();
        Toast.makeText(DefaultMessagesActivity.this, "Offline! Message not sent!", Toast.LENGTH_LONG).show();
    

这工作正常,直到我断开互联网然后重新连接。重连成功后尝试调用sendMessage()方法从数据库发送未发送的消息,出现此错误

E/AbstractXMPPConnection: Exception in authenticated listener
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.Context.sendBroadcast(android.content.Intent)' on a null object reference
 at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:396)
 at com.chatmate.user.chatapp.DefaultMessagesActivity.sendMessage(DefaultMessagesActivity.java:113)
 at com.chatmate.user.chatapp.DefaultMessagesActivity.sendMessageAgain(DefaultMessagesActivity.java:146)
 at com.chatmate.user.chatapp.SmackConnection.showContactListActivityWhenAuthenticated(SmackConnection.java:272)
 at com.chatmate.user.chatapp.SmackConnection.authenticated(SmackConnection.java:229)
 at org.jivesoftware.smack.AbstractXMPPConnection.callConnectionAuthenticatedListener(AbstractXMPPConnection.java:1228)
 at org.jivesoftware.smack.AbstractXMPPConnection.afterSuccessfulLogin(AbstractXMPPConnection.java:572)
 at org.jivesoftware.smack.tcp.XMPPTCPConnection.afterSuccessfulLogin(XMPPTCPConnection.java:377)
 at org.jivesoftware.smack.tcp.XMPPTCPConnection.loginInternal(XMPPTCPConnection.java:395)
 at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:491)
 at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:448)
 at org.jivesoftware.smack.ReconnectionManager$2.run(ReconnectionManager.java:254)
 at java.lang.Thread.run(Thread.java:818)

其中错误DefaultMessagesActivity.java:113 表示DefaultMessagesActivity.this.sendBroadcast(intent1); 这一行。

【问题讨论】:

What is a NullPointerException, and how do I fix it?的可能重复 在调用 DefaultMessagesActivity.this.sendBroadcast(intent1) 之前,我已经使用 if (DefaultMessagesActivity.this.equals(null)) 进行了测试。 如果对象为 null,则在其上调用 .equals 仍会引发 NullPointerException。空检查始终使用!= 运算符。 if (object != null) ... 是正确的语法。 是的,我也使用!= 进行了检查。 IDE 说 Condition 'DefaultMessagesActivity.this != null' is always 'true 【参考方案1】:

private void sendMessage(String message, String receiverJid) 从一个实现ConnectionListener 的类调用。恢复XMPPTCPConnection 后调用connected() 方法,之后调用authenticated()。问题是,当我试图在DefaultMessagesActivity.class 中调用sendMessage 时,调用了DefaultMessagesActivity.this.sendBroadcast(intent1); 行。但是这一行是从@overwrite 方法调用的,这导致在Authenticated Listener 中出现NULL 指向异常。当我试图测试 DefaultMessagesActivity 是否为空时,我发现它从来都不是空的。但是在这个对象中广播对 Authenticated Listener 没有帮助。

解决方案

如果我必须调用sendMessage() 方法来发送离线消息,那么我应该在包含@overwrite 方法connected() 的文件中编写单独的代码。对于广播,我们使用Context.sendBroadcast(intent1);

【讨论】:

以上是关于在与 Smack 4.2 重新连接后发送离线消息时,经过身份验证的侦听器出现异常的主要内容,如果未能解决你的问题,请参考以下文章

为啥重新连接成功时socket.io客户端会发送离线消息?

Smack:ReconnectionManager 在重新连接时发送重复的登录请求

java - 使用 smack4.2 firebase xmpp 发送消息错误

如何在 xmpp smack 或 asmack 中将文件发送给离线用户?

由于 openfire 连接丢失而丢失消息

在 Android Smack 4.2 的消息节点中添加自定义标签