博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 聊天室(一)
阅读量:5167 次
发布时间:2019-06-13

本文共 8492 字,大约阅读时间需要 28 分钟。

         为了提高自己在Android开发上的能力,博主决定写一个类似于QQ、微信的聊天软件。不过,简单的想想之后发现,要实现这样的一个聊天软件,需要学习和掌握的东西还很多。作为一个Android开发的小白,也没有足够的实力能很快对这个APP的开发有很大的突破。

         于是,博主参考《疯狂Android讲义》中关于“Android网络应用”部分。首先从简单的聊天功能进行实现。第一阶段,主要实现的是一个多人聊天室,通过socket以及多线程进行实现。

具体过程为:

  1. Client A、Client B、Client C 分别与Server建立socket连接。
  2. 每建立一个连接Server将把这个socket存储在一个socketList的列表里。
  3. 每当其中一个客户端“说话”时(以Client A 为例),Server收到Client A 发出的消息将会遍历整个socketList,将这条信息广播给当前所有已经建立了socket连接的Client

下面,博主将从服务器端以及Android客户端,对这个实现过程进行详细的介绍:

  • Server

主要实现功能:与客户端建立socket连接;对Client发送的消息进行转发。

MyServer.java

public class MyServer {       static BufferedReader br;       static int index = 0;       public static ArrayList
socketList = new ArrayList<>(); public static void main(String[] args) throws IOException { ServerSocket ss =new ServerSocket(30000); //开启30000号端口 while(true ){ Socket s = ss.accept(); socketList.add(s); new Thread(new ServerThread(s)).start(); } //持续接收来自Client的socket连接,并将socket加入列表 }}
ServerTread.java
public class ServerThread implements Runnable {      Socket s = null;      BufferedReader br = null;             public ServerThread(Socket s) throws IOException{             this.s = s;             br = new BufferedReader(new InputStreamReader(s.getInputStream()                                                                    , "utf-8" ));      }             @Override       public void run() {             try {                  String content = null;                   while((content = readFromClient()) != null){                         for(Socket s : MyServer.socketList){                              OutputStream os = s.getOutputStream();                              os.write((content + "\n").getBytes("utf-8" ));                        }                                   } //遍历整个socketList,将信息写入输出流进行广播            } catch (Exception e) {                  e.printStackTrace();            }      }       private String readFromClient() {             try {                   return br .readLine();            } catch (Exception e) {                  MyServer. socketList.remove(s ); //读取信息失败则移除socket            }             return null ;      }}
  • Client

主要实现功能:与服务器建立socket连接;实现消息的发送与接受。

Chat.java

public class Chat extends Activity {      TextView tv_name;      EditText et_input;      Button bt_send;         ClientThread clientThread;                   private ListView listview ;       private List
mData ; private ChatMessageAdapter mAdapter ; private static final String tag = "Chat"; private Handler handler = new Handler(){ @Override public void handleMessage(android.os.Message msg) { if(msg.what == 0x123){ ChatMessage receiveMsg = (ChatMessage) msg. obj; mData.add(receiveMsg); mAdapter.notifyDataSetChanged(); listview.setSelection(mData .size() - 1); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window. FEATURE_NO_TITLE); setContentView(R.layout. chat); initView(); //初始化view initData(); //初始化数据 clientThread = new ClientThread(handler); new Thread(clientThread ).start(); //启动新线程发送信息 bt_send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final String inputMsg = et_input.getText().toString(); Log. v(tag, "inputMsg: " + inputMsg); if(TextUtils.isEmpty(inputMsg)){ Toast. makeText(Chat.this, "发送消息不能为空!" , Toast. LENGTH_SHORT).show(); } try { ChatMessage cm = new ChatMessage(); cm.setDate( new Date()); cm.setMsg(inputMsg); cm.setType(Type. OUTCOMING); cm.setName( "paul"); mData.add(cm); mAdapter.notifyDataSetChanged(); listview.setSelection(mData .size() - 1); Message msg = new Message(); msg. what = 0x345; msg. obj = inputMsg; et_input.setText("" ); clientThread.revHandler .sendMessage(msg); //发送信息 } catch (Exception e) { e.printStackTrace(); } } }); } private void initData() { mData = new ArrayList
(); String data = et_input.getText().toString(); mAdapter = new ChatMessageAdapter(Chat.this, mData); listview.setAdapter(mAdapter ); } private void initView() { tv_name = (TextView) findViewById(R.id.tv_name); et_input = (EditText) findViewById(R.id.et_input); bt_send = (Button) findViewById(R.id.bt_send); listview = (ListView) findViewById(R.id.id_listview); }

ClientTread.java

public class ClientThread implements Runnable {       private Socket s ;       private Handler handler ;       public Handler revHandler ;            BufferedReader br = null;      OutputStream os = null;             public ClientThread(Handler handler) {             this.handler = handler;      }       @Override       public void run() {             try {                   s = new Socket("10.105.36.51" , 30000); //通过ip地址和端口号连接服务器                   br = new BufferedReader(new InputStreamReader(s.getInputStream()));                   os = s.getOutputStream();                                     new Thread(){                         @Override                         public void run() {                              String content = null;                               try {                                     while((content = br .readLine()) != null){                                          ChatMessage cm =new ChatMessage();                                          cm.setDate( new Date());                                          cm.setMsg(content);                                          cm.setType(Type. INCOMING);                                          cm.setName( "paul");                                                                                    Message msg = new Message();                                          msg. what = 0x123;                                          msg. obj = cm;                                           handler.sendMessage(msg);                                    }                              } catch (IOException e) {                                    e.printStackTrace();                              }                        }                                          }.start();                                    Looper. prepare();                                     revHandler = new Handler(){                         @Override                         public void handleMessage(Message msg) {                               if(msg.what == 0x345){                                     try {                                           os.write((msg. obj.toString() + "\r\n").getBytes("utf-8" )); //将信息写入输出流发送给服务器                                    } catch (IOException e) {                                          e.printStackTrace();                                    }                              }                        }                                          };                  Looper. loop();            } catch (SocketTimeoutException e) {                  System. out.println("网络连接超时!" );            } catch (Exception e) {                  e.printStackTrace();            }      }}

转载于:https://www.cnblogs.com/siguoyi/p/4447573.html

你可能感兴趣的文章
35. Search Insert Position(C++)
查看>>
[毕业生的商业软件开发之路]C#异常处理
查看>>
有关快速幂取模
查看>>
NOI2018垫底记
查看>>
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
js编码
查看>>
Pycharm Error loading package list:Status: 403错误解决方法
查看>>
steps/train_sat.sh
查看>>
转:Linux设备树(Device Tree)机制
查看>>
iOS 组件化
查看>>
(转)Tomcat 8 安装和配置、优化
查看>>
(转)Linxu磁盘体系知识介绍及磁盘介绍
查看>>
命令ord
查看>>
Sharepoint 2013搜索服务配置总结(实战)
查看>>
博客盈利请先考虑这七点
查看>>