Android C/S結構的簡易羣聊應用 學習筆記2

1.功能分析:

服務器端線程類不斷讀取客戶端數據,讀到客戶端數據後,將該數據向所有客戶端發送一次,

客戶端包含兩條線程:

一條將用戶輸入數據寫入Socket對應的輸出流中;

另一條負責讀取Socket對應輸入流中的數據(即從服務器發送過來的數據)。

 2.客戶端實現細節分析:

在客戶端子線程中分別定義向UI線程發送消息的Handler對象(hanler)  和 接收UI線程的消息的Handler對象(recvHandler)。

public class ClientThread implements Runnable{
Handler handler = null;//send msg to UI
Handler recvHandler = null;//recv msg from UI

public ClientThread(Handler handler){
this.handler = handler;
}

@Override
public void run() {
// TODO Auto-generated method stub
try {
new Thread(){
@Override
public void run(){
//child thread  : read data from the server
}
}
}.start();

Looper.prepare();
recvHandler = new Handler(){
@Override
public void handleMessage(Message msg){
//send msg to the server
if(msg.what == MultiThreadClient.SEND_MSG){
try {

os.write((msg.obj.toString()+"\r\n").getBytes("utf-8"));

}
};
Looper.loop();

}

3.Review looper

àHandler的主要作用是發送消息和處理消息,被Handler發送的消息必須被送到指定的MessageQueue,而MessageQueue又是由Looper負責管理的。即希望Handler正常工作,必須在當前線程中有一個Looper對象。         


所以在線程中使用Handler的步驟如下:


4.tips

(1) UTF-8 編碼問題


(2)

pro in server:

read_msg = br.readLine();//alwaysblock  2014  4.3 17:17 ???

solution:

in client

os.write((msg.obj.toString()+"\r\n").getBytes("utf-8"));

(3)

讀取的內容---追加---顯示在文本框中,避免沖掉前面的消息

show.append("\n" +msg.obj.toString());

(4)

0001.android開發中有editetext,當輸入時輸入法會把底部的導航欄頂上去。如何解決?

AndroidManifest.xml文件中界面對應的<activity>里加入

          android:windowSoftInputMode="adjustPan"   鍵盤就會覆蓋屏幕

          android:windowSoftInputMode="stateVisible|adjustResize"   屏幕整體上移

"adjustResize"

 該 Activity主窗口總是被調整屏幕的大小以便留出軟鍵盤的空間

6.Other Pro:

(1) why  alternate  the following two block ,the program cannotrun correctly ?

public void run() {

Block1:

new Thread(){

read data from server

}

Block2:

Looper.prepare();

Send message  to server

Looper.loop();

 

}

(1).MultiThread界面優化  自適應長度  滾動條  將消息頂上去

(2.)其它一些不正確的斷開連接 拋出的異常等問題

java.net.SocketException: Software causedconnection abort: socket write error

         atjava.net.SocketOutputStream.socketWrite0(Native Method)

         atjava.net.SocketOutputStream.socketWrite(Unknown Source)

         atjava.net.SocketOutputStream.write(Unknown Source)

         atServerThread.run(ServerThread.java:49)

         atjava.lang.Thread.run(Unknown Source)

(3)Analysis looper:

子線程中的Handler對象必須是在run方法中創建,纔是真正屬於子線程的.如果在子線程的onCreate方法中創建,則該Handler對象關聯於主線程.
Android
對於在子線程中創建Handler對象有明確的約束,:如果用戶試圖在子線程(run方法)中創建handler對象,而未事先調用Looper.prepare方法,則會直接報錯.



發佈了63 篇原創文章 · 獲贊 9 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章