package com.netease.nim.uikit.cache; import android.text.TextUtils; import com.netease.nim.uikit.NimUIKit; import com.netease.nim.uikit.UIKitLogTag; import com.netease.nim.uikit.common.util.log.LogUtil; import com.netease.nimlib.sdk.NIMClient; import com.netease.nimlib.sdk.Observer; import com.netease.nimlib.sdk.friend.FriendService; import com.netease.nimlib.sdk.friend.FriendServiceObserve; import com.netease.nimlib.sdk.friend.model.BlackListChangedNotify; import com.netease.nimlib.sdk.friend.model.Friend; import com.netease.nimlib.sdk.friend.model.FriendChangedNotify; import com.netease.nimlib.sdk.msg.MsgService; import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; /** * 好友关系缓存 * 注意:获取通讯录列表即是根据Friend列表帐号,去取对应的UserInfo * <p/> * Created by huangjun on 2015/9/14. */ public class FriendDataCache { public static FriendDataCache getInstance() { return InstanceHolder.instance; } /** * 属性 */ private Set<String> friendAccountSet = new CopyOnWriteArraySet<>(); private Map<String, Friend> friendMap = new ConcurrentHashMap<>(); private List<FriendDataChangedObserver> friendObservers = new ArrayList<>(); /** * 初始化&清理 */ public void clear() { clearFriendCache(); } public void buildCache() { // 获取我所有的好友关系 List<Friend> friends = NIMClient.getService(FriendService.class).getFriends(); for (Friend f : friends) { friendMap.put(f.getAccount(), f); } // 获取我所有好友的帐号 List<String> accounts = NIMClient.getService(FriendService.class).getFriendAccounts(); if (accounts == null || accounts.isEmpty()) { return; } // 排除黑名单 List<String> blacks = NIMClient.getService(FriendService.class).getBlackList(); accounts.removeAll(blacks); // 排除掉自己 accounts.remove(NimUIKit.getAccount()); // 确定缓存 friendAccountSet.addAll(accounts); LogUtil.i(UIKitLogTag.FRIEND_CACHE, "build FriendDataCache completed, friends count = " + friendAccountSet.size()); } private void clearFriendCache() { friendAccountSet.clear(); friendMap.clear(); } /** * ****************************** 好友查询接口 ****************************** */ public List<String> getMyFriendAccounts() { List<String> accounts = new ArrayList<>(friendAccountSet.size()); accounts.addAll(friendAccountSet); return accounts; } public int getMyFriendCounts() { return friendAccountSet.size(); } public Friend getFriendByAccount(String account) { if (TextUtils.isEmpty(account)) { return null; } return friendMap.get(account); } public boolean isMyFriend(String account) { return friendAccountSet.contains(account); } /** * ****************************** 缓存好友关系变更监听&通知 ****************************** */ /** * 缓存监听SDK */ public void registerObservers(boolean register) { NIMClient.getService(FriendServiceObserve.class).observeFriendChangedNotify(friendChangedNotifyObserver, register); NIMClient.getService(FriendServiceObserve.class).observeBlackListChangedNotify(blackListChangedNotifyObserver, register); } /** * APP监听缓存 */ public void registerFriendDataChangedObserver(FriendDataChangedObserver o, boolean register) { if (o == null) { return; } if (register) { if (!friendObservers.contains(o)) { friendObservers.add(o); } } else { friendObservers.remove(o); } } public interface FriendDataChangedObserver { void onAddedOrUpdatedFriends(List<String> accounts); void onDeletedFriends(List<String> accounts); void onAddUserToBlackList(List<String> account); void onRemoveUserFromBlackList(List<String> account); } /** * 监听好友关系变化 */ private Observer<FriendChangedNotify> friendChangedNotifyObserver = new Observer<FriendChangedNotify>() { @Override public void onEvent(FriendChangedNotify friendChangedNotify) { List<Friend> addedOrUpdatedFriends = friendChangedNotify.getAddedOrUpdatedFriends(); List<String> myFriendAccounts = new ArrayList<>(addedOrUpdatedFriends.size()); List<String> friendAccounts = new ArrayList<>(addedOrUpdatedFriends.size()); List<String> deletedFriendAccounts = friendChangedNotify.getDeletedFriends(); // 如果在黑名单中,那么不加到好友列表中 String account; for (Friend f : addedOrUpdatedFriends) { account = f.getAccount(); friendMap.put(account, f); friendAccounts.add(account); if (NIMClient.getService(FriendService.class).isInBlackList(account)) { continue; } myFriendAccounts.add(account); } // 更新我的好友关系 if (!myFriendAccounts.isEmpty()) { // update cache friendAccountSet.addAll(myFriendAccounts); // log DataCacheManager.Log(myFriendAccounts, "on add friends", UIKitLogTag.FRIEND_CACHE); } // 通知好友关系更新 if (!friendAccounts.isEmpty()) { for (FriendDataChangedObserver o : friendObservers) { o.onAddedOrUpdatedFriends(friendAccounts); } } // 处理被删除的好友关系 if (!deletedFriendAccounts.isEmpty()) { // update cache friendAccountSet.removeAll(deletedFriendAccounts); for (String a : deletedFriendAccounts) { friendMap.remove(a); } // log DataCacheManager.Log(deletedFriendAccounts, "on delete friends", UIKitLogTag.FRIEND_CACHE); // notify for (FriendDataChangedObserver o : friendObservers) { o.onDeletedFriends(deletedFriendAccounts); } } } }; /** * 监听黑名单变化(决定是否加入或者移出好友列表) */ private Observer<BlackListChangedNotify> blackListChangedNotifyObserver = new Observer<BlackListChangedNotify>() { @Override public void onEvent(BlackListChangedNotify blackListChangedNotify) { List<String> addedAccounts = blackListChangedNotify.getAddedAccounts(); List<String> removedAccounts = blackListChangedNotify.getRemovedAccounts(); if (!addedAccounts.isEmpty()) { // 拉黑,即从好友名单中移除 friendAccountSet.removeAll(addedAccounts); // log DataCacheManager.Log(addedAccounts, "on add users to black list", UIKitLogTag.FRIEND_CACHE); // notify for (FriendDataChangedObserver o : friendObservers) { o.onAddUserToBlackList(addedAccounts); } // 拉黑,要从最近联系人列表中删除该好友 for (String account : addedAccounts) { NIMClient.getService(MsgService.class).deleteRecentContact2(account, SessionTypeEnum.P2P); } } if (!removedAccounts.isEmpty()) { // 移出黑名单,判断是否加入好友名单 for (String account : removedAccounts) { if (NIMClient.getService(FriendService.class).isMyFriend(account)) { friendAccountSet.add(account); } } // log DataCacheManager.Log(removedAccounts, "on remove users from black list", UIKitLogTag.FRIEND_CACHE); // 通知观察者 for (FriendDataChangedObserver o : friendObservers) { o.onRemoveUserFromBlackList(removedAccounts); } } } }; /** * ************************************ 单例 ********************************************** */ static class InstanceHolder { final static FriendDataCache instance = new FriendDataCache(); } }