使用環信時遇見最大的坑 嗚嗚嗚嗚~~

這篇其實就一句話:onMessageChanged(EMMessage message, Object change) 中的change別亂打印就行了

簡介

公司項目要加即時通訊,於是我和老闆說有兩種方法 :一是自己擼 比如openfire+asmark ;二是 選擇第三方的 。
老闆二話沒說 就選了第一種,於是我又和老闆說 : 第一中開發成本大 而且不一定體育第三方做的好(其實我們公司肯定沒有人家做的好啦!),老闆沉思了一會問:“第三方的都有神馬” 於是就說了一些常見的 網易雲信、環信、融雲這些。
老闆上網搜了搜 說用’環信’吧。我們這些做開發的無所謂,用哪家都行 於是就選擇了環信開始開發。

環信easeui

進入環信官網,選擇了即時通訊雲,看了下文檔 發現有easeui這個東西,於是就和demo一起下載了,我看demo用的就是easeui,用的還算挺方便,已經打算用了,可是突然想到 公司的需求:發送圖片、文字 即可。用這個是不是有點浪費資源了,於是打算自己擼一個,照着easeui,把該弄成自定義控件的 弄成自定義控件,該初始化的初始化……

做了一個小demo,登陸、註冊、發送文本消息、接收消息(Log輸出的),感覺都沒問題了,然後就去擼界面了。我用的是RecyclerView。
寫界面時候出了一下小問題,是view複用時候 錯誤現象,由於當時的馬虎,耽擱了好久才解決

view複用錯誤總結:
            1. 加載的數據有網絡數據,也就是異步加載顯示的時候沒有處理好
            2.  view使用前沒有初始化一些設置,或者是使用後沒有進行相關的設置。(這個就是我犯的錯誤,我的view默認隱藏,當消息類型變化時候忘記對其進行初始化的設置了)
            3. 數據綁定方法中的position使用錯誤(這個是一個5年經驗的哥哥告訴我的)
            4. 消息類沒有處理好(比如A類型 發送,B類型接收。綁定相應的佈局)

終於發送的文本消息可以正常顯示了,測試下發送圖片消息吧,這可倒好 問題一下就來了,來的那麼突然。

先看這兩個接口:
EMCallBack 這個接口的發送消息的監聽
EMMessageListener 這個接口是接收消息的監聽

接收文本時候兩個接口都正常工作。可是一旦接收了非文本類型消息時候就完蛋了。
可以顯示本次接收的消息(比如這次接收的是圖片消息),但是下次的消息就說什麼都接收不到了,因爲連監聽裏的log都沒打。

EMMessageListener listener = new EMMessageListener() {
        @Override
        public void onMessageReceived(  List<EMMessage> mes) {
            Log.e(TAG, "收到消息:" + mes.toString());
        }

        @Override
        public void onCmdMessageReceived(List<EMMessage> messages) {
            //收到透傳消息
            Log.e(TAG, "收到透傳消息:" + messages.toString());
        }

        @Override
        public void onMessageReadAckReceived(List<EMMessage> messages) {
            //收到已讀回執
            Log.e(TAG, "收到已讀回執:" + messages.toString());
        }

        @Override
        public void onMessageDeliveryAckReceived(List<EMMessage> message) {
            //收到已送達回執
            Log.e(TAG, "收到已送達回執:" + message.toString());
        }

        @Override
        public void onMessageChanged(EMMessage message, Object change) {
            //消息狀態變動
            Log.e(TAG, "消息狀態變動:" + message.toString()+"---"+change.toString());
        }
    };

我們執行這些操作:發送“1111”、發送“2222”、發送圖片消息、發送“3333”、發送“4444”;
這裏寫圖片描述
先看理想情況情況的Log:
這裏寫圖片描述
實際輸出的Log:
這裏寫圖片描述

反正當時的我是懵逼狀態,遇到問題時候是週五,這個問題一直拖到下週二才解決(中間做了很多別的事情),由於公司沒有技術大牛,只能靠我一個android ,與是我開始看官方的各種demo 什麼完整版的、簡版的 都去看了,不看還好,看了之後就又懵逼了,寫的也沒有錯 問別人也沒有錯,問客服也沒有錯,但爲什麼就是不好使呢?

想想也怪,監聽一次後就不好使了,其實不光EMMessageListener 不好使了,連EMCallBack也不好使了!!

去解決問題

於是我開始各種嘗試:改變環境 換 jdk,換gradle 無果
環信的社區發帖,回覆就是一套官腔,好像我騙他們似的 無果
讓朋友看我代碼 無果
更可氣的是,新建demo,同樣的測試,還是tmd不行~

於是我開始質疑sdk問題(現在想想也挺二的,人家那麼多產品都跑着呢 怎麼可能是sdk問題),又去騷擾客服, 到最後。。。。 客服一看見我的問題就知道是我了(可能也是巧合)

解決!

找了一個官方demo,把聊天界面的全部刪掉,只剩下接收消息。測試 好使~

官方demo接收消息代碼:

 EMMessageListener msgListener = new EMMessageListener() {

        @Override
        public void onMessageReceived(List<EMMessage> messages) {
            Log.e(TAG, messages.toString());
        }

        @Override
        public void onCmdMessageReceived(List<EMMessage> messages) {
            // 收到透傳消息
        }

        @Override
        public void onMessageReadAckReceived(List<EMMessage> messages) {
            // 收到已讀回執
        }

        @Override
        public void onMessageDeliveryAckReceived(List<EMMessage> message) {
            // 收到已送達回執
        }

        @Override
        public void onMessageChanged(EMMessage message, Object change) {
            // 消息狀態變動
        }
    };

我將我自己的監聽將其替換掉:

EMMessageListener listener = new EMMessageListener() {
        @Override
        public void onMessageReceived(  List<EMMessage> mes) {
            Log.e(TAG, "收到消息:" + mes.toString());
        }

        @Override
        public void onCmdMessageReceived(List<EMMessage> messages) {
            //收到透傳消息
            Log.e(TAG, "收到透傳消息:" + messages.toString());
        }

        @Override
        public void onMessageReadAckReceived(List<EMMessage> messages) {
            //收到已讀回執
            Log.e(TAG, "收到已讀回執:" + messages.toString());
        }

        @Override
        public void onMessageDeliveryAckReceived(List<EMMessage> message) {
            //收到已送達回執
            Log.e(TAG, "收到已送達回執:" + message.toString());
        }

        @Override
        public void onMessageChanged(EMMessage message, Object change) {
            //消息狀態變動
            Log.e(TAG, "消息狀態變動:" + change.toString());
        }
    };

於是發現又不好使了!!!
我開始檢查包,接口名 方法名,都沒問題。到最後我將所有Log都刪掉—-測試發現,好使了~

於是我就懵逼了 究竟是哪個log影響了監聽呢,到最後發現了onMessageChanged

只有將onMessageChanged參數中的 Object change 一輸出,就會使所有監聽都不好使。

onMessageChanged中的Object change是幹什麼的呢?
首先看環信文檔中EMMessageListener的介紹:

EMMessageListener消息偵聽接口,可以用來偵聽消息接受情況,成功發送到對方手機後會有回執, 對方閱讀了這條消息也會收到回執。 發送消息過程中,消息的ID會發生改變,由最初本地生成的一個UUID,變更爲服務器端生成的全局唯一的ID,這個ID在所有使用Hyphenate SDK的 設備上都是唯一的。 應用需要實現此接口來監聽消息變更狀態

onMessageChanged 介紹:

void com.hyphenate.EMMessageListener.onMessageChanged   (EMMessage  message,Object change )     
接受消息發生改變的通知,包括消息ID的改變。消息是改變後的消息。
參數:
message 發生改變的消息
change  change, 包含改變的信息

於是將項目中change的Log刪掉,項目愉快的跑了起來~

總結

當時腦殘,就應該直接去看監聽中爲什麼人家的好使我的不好使,刪除其他代碼後 找出不同與自己的代碼,哪怕是輸出的log。當然了 log是最後拍查的
我猜這次犯的錯誤就是因爲有些變量 取了一次值之後 就被回收或者清除了
爲什麼我這麼說呢,猜的啊~因爲我也不知道爲什麼取了一次值之後就沒有了,只能往這裏聯繫了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章