編輯:關於Android編程
前言
很久沒寫BLOG了,之前在寫Android聊天室的時候答應過要寫一個客戶(好友)之間的聊天demo,Android 基於Socket的聊天室已經實現了通過Socket廣播形式的通信功能。
以下是我寫的一個類似現在多數聊天軟件的冒泡聊天APP。全部功能都是自己的想法,對於現在市面上成功的例子是怎麼實現的,我還不了解。所以讀者可只做參考學習,也可以分享您的案例給我。
功能
基本原理
之前的聊天室原理:每當客戶端Socket連接到該ServerSocket之後,程序將對應Socket加入clients集合中保存,並為該Socket啟動一條線程,該線程負責處理該Socket所有的通信任務,當服務器線程讀到客戶端數據之後,程序遍歷clients集合,並將該數據向clients集合中的每個Socket發送一次
一對一的聊天:Server通過Map把Clients的Socket都儲存起來,把Client用戶ID作為Map的key,當A發送信息給B時,服務器搜索出B的Socket,建立他們的通信通道。
服務器Server
這次我在服務器加入了2個Socket集合,一個用來處理用戶Online/Offline,另一個則專門用於處理用戶之間的通信信息傳遞
static Map<String, Socket> socketMap = new HashMap<String, Socket>(); static Map<String, Socket> onlineMap = new HashMap<String, Socket>();
Clients 上線,下線動作,Server都會經過篩選然後通知其在線的好友,Clients收到好友的在線狀態然後修改Friends List。
//save client's name ,online //... getnameString = str.substring(config.PROTOCOL_KEY.length()+config.PROTOCOL_ONLINE.length()); Server.onlineMap.put(getnameString, s); //... //update online friends DataOutputStream onlineDOS = new DataOutputStream (Server.onlineMap.get(clientKey).getOutputStream()); onlineDOS.writeUTF(config.PROTOCOL_FRIENDS_START+onlineString+config.PROTOCOL_FRIENDS_END); onlineDOS.flush();
關於聊天,我是通過一個自定義加密符來給每個Client做標志的,例如:Client A發出的信息,該條信息的頭部帶有一條服務器和客戶端都會識別的特殊符號,通過字符處理,找出該條信息的用戶信息;以此類推,Client A的通信對象也是用這個方法
我們找到ClientA的目標對象後,找出這個Socket通道,他們就可以一對一的對話了
//send msg to friend DataOutputStream ndos = new DataOutputStream (Server.socketMap.get(forname).getOutputStream()); ndos.writeUTF(fromname+date+"\n"+forchat); ndos.flush();
關於離線信息,這個主要是服務器承擔的功能,我是使用mySql保存數據的。Client A 向離線狀態的Client B發送一條信息,Server會判斷Client B是否在線,如果是離線狀態,服務器則把該信息先保存在mySql裡;當Client B上線時,服務器會查找它的離線信息,如果有未讀信息,則會及時發送。Client B就能收到離線信息了 ( ̄ˇ ̄)
客戶端 Clients
關於聊天,為了能夠實現同時與多個好友聊天(不同窗口線程),這裡用了ContentProvider監視聊天數據的變化,使不在當前聊天窗口的Activity也能收到好友的信息拼打印。
//監視聊天數據的變化 getContentResolver().registerContentObserver(DataChangeProvider.CONTENT_URI,true, cob);
那後台是怎麼樣接收好友發來的信息的呢?上面Server裡說過,有一個SocketMap的集合,而這個集合就是記錄用戶的通信Socket,當有信息的時候,客戶端後台的WaitMsg()會接到發來的信息並做處理。
private Runnable waitThread = new Runnable() { public void run() { System.out.println("wait running!"); WaitMsg(); } };
關於Online/Offline狀態,好友列表Activity ReceiveMsg()會監視Server發送的好友狀態信息,及時更新好友列表ListActivity。
//更新好友數據庫 fanDS.updateData(reMsg,name); //獲取好友列表 fansArray = fanDS.getFans(); friends = new Friends(fansArray,reMsg,name); friendList = friends.getFriends();
總結
相對聊天室而言,一對一的聊天主要是對每個Client的Socket都標志記錄起來,讓每個通訊動作有了目標對象;Server作為信使把兩者的Socket對接,使兩者可以通信聊天。
這是在 TCP/IP協議下的 C/S 模式通信方式,還有UDP協議,P2P模式下的通信方式的值得再去學習。
現在把代碼直接放上博客園,Download:demo
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
紅米pro於昨日剛剛與大家見面,對於這款售價為1499的高端紅米手機,很多人將它與樂視2pro進行對比,那麼到底紅米pro和樂視2pro哪個好呢?相信很多用
1.總結之前學習的關於屬性動畫的筆記 和 學習了郭霖大神的 屬性動畫高級用法相關的博客之後的記錄2.學習loading… 2.1補間動畫 PK 屬性動畫在篇
源碼下載 之前用zxing做開發,各種奇葩問題,橫屏修等等,而且性能也不搞。被測試批了,沒辦法後來換了zbar。性能好多了。 直接上圖,看看效果 2.界面上的
前言在學習Android內存性能優化時,發現需要對Android系統的內存概況得有個概況了解,便有了此篇文章。這篇文章僅僅介紹相關於內存的,即輔助理解 官方文檔 How