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

Exception in authenticated listener while Sending offline message after re connection with Smack 4.2

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

中配置的消息
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();
    }
}

这个用于从消息中调用 sendMessage() 方法 activity

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.run(ReconnectionManager.java:254)
 at java.lang.Thread.run(Thread.java:818)

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

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

Solution

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