Android 使用环信sdk时,设置view的Invisible相关属性时,失效的bug

 先直接告诉问题原因吧,环信的消息监听的回调是在子线程的,而我在消息监听的回调中直接更新了ui,环信又进行异常捕获,导致走到设置显示或隐藏的代码时无效了,因为捕获了异常,所以很难从log中发现原因,下面介绍详细情况。

 我遇到的问题是,我在项目中监听到环信新消息后,去查询未读消息数,并根据数量如果小于等于0则不显示对应的view:view.setVisibility(View.INVISIBLE);;其他则显示view:view.setVisibility(View.VISIBLE);。但是只要我隐藏后,就再也无法把这个view显示出来了,网上看了好多资料,都是说view.clearAnimation(),但是对我不是很起作用,为什么说是不怎么起作用呢,因为他确实有时候会显示出来,但是是我发很多消息后,他会突然出来,并不是未读消息大于0的时候,就立马出来;代码如下:

//声明监听器
private EMMessageListener msgListener = new EMMessageListener() {

        @Override
        public void onMessageReceived(List messages) {
             //收到消息,查询未读消息数
             queryChatUnReadedMsg();
        }

        @Override
        public void onCmdMessageReceived(List messages) {
        }

        @Override
        public void onMessageReadAckReceived(List list) {
        }

        @Override
        public void onMessageDeliveryAckReceived(List list) {
        }

        @Override
        public void onMessageChanged(EMMessage message, Object change) {
        }
    };

//在oncreate()中注册监听
EMClient.getInstance().chatManager().addMessageListener(msgListener);

/**
* 获取未读消息数量
*/
private void queryChatUnReadedMsg() {
      ...省略查询未读数量代码
       showChatUnReadedMsg(unreadMsgCount);
    }

/**
* 根据数量显示或隐藏view
* tvChatMsgCount就是一个未读消息的小图标,显示未读消息数量
*/
public void showChatUnReadedMsg(int unreadMsgCount) {
        // tvChatMsgCount.clearAnimation(); //这个api没作用所以注释掉了
        if (unreadMsgCount <= 0) {
            tvChatMsgCount.setText("");
            tvChatMsgCount.setVisibility(View.INVISIBLE);
        } else if (unreadMsgCount >= 100) {
            tvChatMsgCount.setText("99+");
            // 失效,不起作用
            tvChatMsgCount.setVisibility(View.VISIBLE);
        } else {
            tvChatMsgCount.setText(unreadMsgCount + "");
            // 失效,不起作用
            tvChatMsgCount.setVisibility(View.VISIBLE);
        }
    }

整个代码就是上面这样,没发现问题,找了好久,试着在调用showChatUnReadedMsg()方法时,在主线程调用,结果就正常了,修改queryChatUnReadedMsg()中的代码如下:

/**
* 获取未读消息数量
*/
private void queryChatUnReadedMsg() {
        ...省略查询未读数量代码
        runOnMainThread(new Runnable() {
                @Override
                public void run() {
                    showChatUnReadedMsg(unreadMsgCount);
                }
            });
    }

试了两种方式,发现EMMessageListener msgListener中的回调不是在主线程的,所以估计是因为在非主线程设置这个属性导致的,但是为什么不会崩溃报错(应该是环信内部做了异常捕获);

总结

根据我的推测,其实设置不起效的原因,就是在非主线程更新了ui,而由于环信内部做了异常捕获,所以app也不会崩溃,log中也不会出现异常,所以谨记一点:环信的消息监听回调是在非主线程的,如果涉及更新ui一定记得切换到主线程;
哎,这么低级的bug,弄了这么久,太丢人了。以后用sdk前一定要认真看他们的文档和demo。

你可能感兴趣的:(Android 使用环信sdk时,设置view的Invisible相关属性时,失效的bug)