Android C/S结构的简易群聊应用 学习笔记2

来源:互联网 发布:淘宝卖家链接能点吗 编辑:程序博客网 时间:2024/06/08 17:24

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方法,则会直接报错.



0 0
原创粉丝点击