实现聊天界面的代码

可能现在很多应用中都会用到两个人活着多人互动的界面,当然,对于这个界面,我们别无选择的都会用到客户端以及服务端的交互。

这里主要的思路就是通过客户端接受用户的输入,然后,我们把输入的值通过一个请求发送给服务端,然后再通过一个方式得到服务端返回的数据,当然,这里想要不停的接受客户端的访问,所以在服务端我们必须要把条件设为true

这里我们做一个简单的客户端界面,当然,这里我们也可以做成像QQ聊天界面那样的界面,然后可以做成一个多人聊天室。(网络聊天室)。

 

/***

 * 

 * @author William 这里我们要演示的是多线程聊天功能

 * 

 * */

public class AndroidThreadClientActivity extends Activity {

/** Called when the activity is first created. */

// define a key这里我们就是给客户端一个端口,然后让他们进行交互

public static final int PORT = 8080;

//这里的ip地址是在无网的状态下也可以进行连接的ip,那么大家就该知道是什么了吧(虚列机的ip

public static final String HOST = "10.0.2.2";

private EditText sentText;

private EditText getText;

Socket s;

// create a visible t

// 创建消息对象

Handler handler;

String get_text;

// 设置菜单的listView留言人的数组

 

// 输出流对象

OutputStream output;

 

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

// 构建视图控件

getText = (EditText) findViewById(R.id.get);

sentText = (EditText) findViewById(R.id.send);

// 立即与服务端连接

try {

s = new Socket(HOST, PORT);

 

System.out.println("he is " + s.getInetAddress() + "的用户--->1");

 

output = s.getOutputStream();

 

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// sendBtn.setOnClickListener((android.view.View.OnClickListener) this);

// 使用类方法创建Handler

handler = new Handler() {

 

@Override

public void handleMessage(Message msg) {

/* super.handleMessage(msg); */

// 判断是否是子线程传过来的信息

if (msg.what == 3) {

// 将服务器端的消息追加的edittext控件进行显示

System.out.println("这里我是去读线程消息传过来的值------>6");

get_text = msg.obj.toString();

getText.append(get_text);

// 启动子线程,每个线程处理对应的socket

 

MyThread my = new MyThread(s, handler);

new Thread(my).start();

System.out.println("我已经启动了线程clientthread----------->5");

 

 

} else {

 

System.out.println("不好意思,线程获取错误");

}

 

}

};

 

}

 

public void onAction(View v) {

// 将输入文本框的文本信息写出流

try {

System.out.println("我写的内容是" + sentText.getText().toString());

output.write((sentText.getText().toString() + " ")

.getBytes("utf-8"));

// output.write(sentText.getText().toString() .getBytes());

System.out.println(sentText.getText().toString());

 

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

sentText.setText("");

 

}

 

}

这里我们把消息实现消息的线程建立成了一个外部类,当然,这里我们也可以建立成一个内部类:

 

import android.os.Handler;

import android.os.Message;

//这里我开始也以为会有一些问题,那就是我们见过的都是继承Thread,而这里呢?我们这里是直接继承了runable

public class MyThread  implements Runnable{

 

private Socket s;

private Handler handler;

BufferedReader br = null;

String str;

/**

 * to create the funcation

 * */

public MyThread(Socket s, Handler h) {

 

this.s = s;

this.handler = h;

try {

//这里我开始是想要进行测试的,结果发现有问题,所以,还是用下面这种的吧。

一种:

// // deine a inputstream

// InputStream ip = s.getInputStream();

// // define a byte

// byte[] mByte = new byte[1024];

// // input the byte int the

// ip.read(mByte);

//二种:

br = new BufferedReader(new InputStreamReader(

s.getInputStream(), "utf-8"));

System.out.println("str is ------>----->2"+br);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

@Override

public void run() {

 

String content = "haha";

System.out.println("我在run里面了------------>3");

 

// TODO Auto-generated method stub

// to read the content

//这里我是用的true,当然我只是为了测试,你们就大可不必这样了

while (true) {

System.out.println("我在run里面了------------>4");

//Message message = handler.obtainMessage();

Message message=new Message();

message.what = 3;

message.obj = content;

handler.sendMessage(message);

 

}

 

}

以上就是一个实现一个简单聊天的客户端过程。

当然,这里呢,我也将服务端的代码贴了出来:

package cn;

 

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;

 

public class ThreadServer {

 

// 定义保存所有socket里面的的list

public static List<Socket> socketList = new ArrayList<Socket>();

 

/**

 * 

 * @author Wiuizm

 * */

public static void main(String[] args) {

 

// 创建serversocket对象,使用端口8080

try {

System.out.println("我在服务端的main方法里面");

ServerSocket ss = new ServerSocket(8080);

 

// 不断的轮询,然后接受客户端的访问

while (true) {

// 创建socket对象

Socket s = ss.accept();

System.out.println("he is "+s.getInetAddress()+"的用户");

socketList.add(s);

System.out.println(socketList);

// 客户端连接后,我们启动第一条线程,然后开始为客户端服务

new Thread(new serverThreas(s)).start();

 

}

 

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

//这里也可以建立一个内部类或者外部类,当然,我这里是建立了一个外部类,方便看吧,老师也曾经说过,我们把能分开的就分开吧,这样在每一个类里面就不会看到太多的代码量。

 

//这里是一个外部线程类:

public class serverThreas implements Runnable{

 

// 定义当前处理线程的socket

Socket s = null;

// 该线程处理的socket所对应的输入流

BufferedReader br = null;

 

/***

 * 构造党法

 * 

 * */

 

public serverThreas(Socket s) {

System.out.println("我在socketthread里面");

this.s = s;

// 初始化socket对应的输入流

try {

br = new BufferedReader(new InputStreamReader(

s.getInputStream(), "utf-8"));

System.out.println(br);

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

 

@Override

public void run() {

// TODO Auto-generated method stub

String content = null;

while ((content = readMessageFormClient()) != null) {

 

// 遍历socketlist中的每个socket,将读取到的内容行每个socket发送一次

for (Socket s : ThreadServer.socketList) {

// 创建输出流对象

OutputStream output;

try {

output = s.getOutputStream();

output.write((content + " ").getBytes("utf-8"));

output.flush();

output.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

}

}

 

}

private String readMessageFormClient() {

 

try {

System.out.println("this content is ----->"+br.readLine());

return br.readLine();

} catch (IOException e) {

// TODO Auto-generated catch block

// 如果发生异常

ThreadServer.socketList.remove(s);

e.printStackTrace();

}

return null;

 

}

 

}

好了,现在客户端和服务端我们都算有一点思路了,不知道大家看了有清晰一点没?如果有什么不对劲的地方,希望大家还是狠狠的提出来,谢谢。

 

 

 

 

一切只是为了充实自己!!stay hungry and stay foolish!!
原文地址:https://www.cnblogs.com/Catherine-Brain/p/3543770.html