1. 程式人生 > >這兩天除錯環信的心得

這兩天除錯環信的心得

一.整合就不多說了,官方文件都有的,可以自己去看:
整合進來有一個小的問題就是設定暱稱和頭像。

1、在登入的時候,把自己登入成功時後臺返回的資訊儲存到sharedpreferences中,需要包含需要的頭像和暱稱。

new Thread(new Runnable() {
      @Override
      public void run() {
        EMClient.getInstance().login(username, password, new EMCallBack() {
          @Override
          public void onSuccess()
{ // 登陸成功,儲存使用者暱稱與頭像URL AppSPUtils.setValueToPrefrences("name", loginBean.getName()); AppSPUtils.setValueToPrefrences("logoUrl", loginBean.getLogoUrl()); // 將自己伺服器返回的環信賬號、暱稱和頭像URL設定到幫助類中。 DemoHelper.getInstance().getUserProfileManager().updateCurrentUserNickName(loginBean.getName()
)
; DemoHelper.getInstance().getUserProfileManager().setCurrentUserAvatar(loginBean.getLogoUrl()); DemoHelper.getInstance().setCurrentUserName(loginUser.getHxId()); // 環信Id // ------以下參考demo中的,載入群組和載入訊息。然後跳轉到首頁-------

2、AppSPUtils是個人寫的一個工具類,大家可以自己寫一個,給出參考程式碼。

public class
AppSPUtils { private final static int MODE_SPEC = android.os.Build.VERSION.SDK_INT <= 10 ? 0 : Context.MODE_MULTI_PROCESS; public static SharedPreferences getSharedPreferences(String name) { return MainApplication.getContext().getSharedPreferences(name, Context.MODE_PRIVATE | MODE_SPEC); } public static SharedPreferences getAppSharedPreferences() { return getSharedPreferences(Constants.SP_APP); } public static String getValueFromPrefrences(String key, String defaultValue) { return getValueFromPrefrences(getAppSharedPreferences(), key, defaultValue); } public static void setValueToPrefrences(String key, String value) { try { SharedPreferences preferences = getAppSharedPreferences(); if (null != preferences) { preferences.edit().putString(key, value).commit(); } } catch (Exception e) { e.printStackTrace(); } } // 退出登入時要呼叫 public static void clean() { try { SharedPreferences preferences = getAppSharedPreferences(); if (null != getAppSharedPreferences()) { getAppSharedPreferences().edit().clear().commit(); } } catch (Exception e) { e.printStackTrace(); } } }

3、儲存好自己的資訊後,已經成功了四分之一,現在是如何將自己的頭像暱稱等資訊傳送出去,最簡單的就是使用擴充套件訊息了,在ChatActivity中可以看到,基本上只做了一件事,保證只有一個ChatActivity,那我們的程式碼在哪裡?就在ChatFragment裡面。找到程式碼,可以看到其實它是繼承自EaseChatFragment,很多內容在easeui中已經做好了。這時你會發現ChatFragment類中有一個擴充套件屬性的說明,沒錯,就是這個方法,把你要傳送的內容盡情的傳送吧,現附上傳送頭像和暱稱的程式碼:

@Override
  public void onSetMessageAttributes(EMMessage message) {
    if (isRobot) {
      // 設定訊息擴充套件屬性
      message.setAttribute("em_robot_message", isRobot);
    }
    // 通過擴充套件屬性,將userPic和userName傳送出去。
    String userPic = AppSPUtils.getValueFromPrefrences("logoUrl", "");
    if (!TextUtils.isEmpty(userPic)) {
      message.setAttribute("userPic", userPic);
    }
    String userName = AppSPUtils.getValueFromPrefrences("name", "");
    if (!TextUtils.isEmpty(userName)) {
      message.setAttribute("userName", userName);
    }
  }

4、傳送完成,你已經完成了四分之二的任務了。傳送完成後,肯定需要一個接收,其實demo中的廣播已經接收好了,那麼我們跟隨著廣播的腳步,來到DemoHelper這個類,初次看這個類,都是雲一樣的感覺,經過一番查詢,發現有個onMessageReceived的方法,並且還有註釋“全域性監聽”,趕緊開工,試試接收吧,可以自己打一下log出來看是不是拿到了我們要的。並且照著demoHelper中的儲存方法,將接收到的內容儲存起來。

@Override
    public void onMessageReceived(List<EMMessage> messages) {
      for (EMMessage message : messages) {
        message.setMsgTime(System.currentTimeMillis());
        //************接收並處理擴充套件訊息***********************
        String userName = message.getStringAttribute("userName", "");
        String userPic = message.getStringAttribute("userPic", "");
        String hxIdFrom = message.getFrom();
        EaseUser easeUser = new EaseUser(hxIdFrom);
        easeUser.setAvatar(userPic);
        easeUser.setNick(userName);
        // 存入記憶體
        getContactList();
        contactList.put(hxIdFrom, easeUser);
        // 存入db
        UserDao dao = new UserDao(MainApplication.getContext());
        List<EaseUser> users = new ArrayList<EaseUser>();
        users.add(easeUser);
        dao.saveContactList(users);
        getModel().setContactSynced(true);
        // 通知listeners聯絡人同步完畢
        notifyContactsSyncListener(true);
        if (isGroupsSyncedWithServer()) {
          notifyForRecevingEvents();
        }
        // ******************擴充套件資訊處理完成**********************
        EMLog.d(TAG, "onMessageReceived id : " + message.getMsgId());
        // 應用在後臺,不需要重新整理UI,通知欄提示新訊息
        if (!easeUI.hasForegroundActivies()) {
          getNotifier().onNewMsg(message);
        }
      }
    }

5、資訊都收到了,就差最後一步就可以顯示了,不知道你們是不是激動,反正我是激動了。那在哪裡進行顯示呢?還是在DemoHelper中,找到getUserInfo方法,程式碼如下:private EaseUser getUserInfo(String hxId) {// 獲取user資訊,demo是從記憶體的好友列表裡獲取,// 實際開發中,可能還需要從伺服器獲取使用者資訊,// 從伺服器獲取的資料,最好快取起來,避免頻繁的網路請求

private EaseUser getUserInfo(String hxId) {
    // 獲取user資訊,demo是從記憶體的好友列表裡獲取,
    // 實際開發中,可能還需要從伺服器獲取使用者資訊,
    // 從伺服器獲取的資料,最好快取起來,避免頻繁的網路請求
    if (hxId.equals(EMClient.getInstance().getCurrentUser())) {
      EaseUser currentUserInfo = getUserProfileManager().getCurrentUserInfo();
      return currentUserInfo;
    }
    EaseUser easeUser;
    if (contactList != null && contactList.containsKey(hxId)) {
    } else { // 如果記憶體中沒有,則將本地資料庫中的取出到記憶體中。
      getContactList();
    }
    // // TODO 獲取不在好友列表裡的群成員具體資訊,即陌生人資訊,demo未實現
    // if (user == null && getRobotList() != null) {
    // user = getRobotList().get(hxId);
    // }
    easeUser = contactList.get(hxId);
    if(easeUser == null){
      easeUser = new EaseUser(hxId);
    } else {
      if(TextUtils.isEmpty(easeUser.getNick())){ // 如果名字為空,則顯示環訊號碼
        easeUser.setNick(easeUser.getUsername());
      }
    }
    return easeUser;
  }

OK,大功告成,到這裡你的頭像已經可以顯示了。。恭喜你!有朋友還有疑問,為什麼頭像是方形的,要變成圓形怎麼辦?指個路,在easeui中的utils包下,找到EaseUserUtils,這裡就是顯示使用者頭像和使用者暱稱的地方,通過Glide可以輕鬆顯示圓形頭像,百度有很多方法,這裡就不多講了,同樣,你也可以通過其他圖形載入框架來完成。很多朋友不明白擴充套件訊息的是什麼東西,也不明白為什麼照著程式碼敲就能夠完成頭像的顯示,那下面就給大家粗淺的講講所涉及到的邏輯關係。擴充套件訊息:就是你每一次傳送訊息,都會附帶在你傳送內容上面的額外訊息,他會隨著你的內容傳送出去,每次會多一點點流量,但微乎其微,個人認為並無多大影響。顯示頭像邏輯:區分為本地化快取和執行記憶體快取,在demoHelper中可以發現,有一個成員變數private Map contactList; 這個就是用來儲存在執行記憶體快取的,只有通過執行快取,顯示頭像是最順暢的,如果每次都從資料庫中讀取的話,聊天介面會比較卡,有朋友儲存在SP裡面,以ID做為KEY,頭像和暱稱等拼接做為value進行快取,取出後再拆分開分別取值,據說是不卡,大家可以試一下。本地化儲存是為了在每次開啟軟體的時候,從本地儲存中拿到執行記憶體中使用做準備,大家可以認真看看demoHelper和MainActivity中的程式碼。———————————————————————————-講了方法2設定頭像,那麼方法1,個人不推薦,但這裡給出處理的過程,如有個別有需求的,可以按方法1來處理:1、登入成功後,在手機子執行緒,訪問你們的後臺伺服器,拿到所有好友的環信ID,頭像,暱稱。然後按上面的儲存方法,儲存到本地中,完成後傳送廣播或EventBus之類到,重新整理訊息介面和ChatFragment。2、在getUserInfo中,寫和上面擴充套件訊息一樣的內容,將如果執行快取和本地都拿不到,則發起網路請求到後臺獲取頭像,等請求到內容後,再發出廣播或EventBus通知重新整理訊息介面和ChatFragment。————————————————————————————-以上僅為本人在開發過程中的一點小小心得,demo中的儲存運存和本地儲存的方法,大家也可以單獨寫,並不會影響程式的執行

監聽傳送過來的訊息的程式碼 在主頁面中實現:

EMMessageListener messageListener = new EMMessageListener() {

        @Override
        public void onMessageReceived(List<EMMessage> messages) {
            // 提示新訊息
            for (EMMessage message : messages) {
                DemoHelper.getInstance().getNotifier().onNewMsg(message);
            }
            refreshUIWithMessage();
        }

        @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) {
        }
    };

    private void refreshUIWithMessage() {
        runOnUiThread(new Runnable() {
            public void run() {
                // 重新整理bottom bar訊息未讀數
                // 當前頁面如果為聊天曆史頁面,重新整理此頁面
                if (conversationListFragment != null) {
                    conversationListFragment.refresh();
                }
            }
        });
    }

在主頁面中實現:

@Override
    protected void onResume() {
        super.onResume();
        EMClient.getInstance().chatManager().addMessageListener(messageListener);
    }

    @Override
    protected void onStop() {
        EMClient.getInstance().chatManager().removeMessageListener(messageListener);
        super.onStop();
    }