ym——Android从零开始(27)(山寨版微信-下)(新)
来源:互联网 发布:社会发展统计数据库 编辑:程序博客网 时间:2024/05/29 04:50
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!
山寨版微信(下)
昨天 我们完成 上线列表刷新。
聊天:
消息:
用户发送:
只需要显示客户端的消息。
一个人可以和多个人聊天。
聊天的内容存放在哪里?数据库 内存 文件
你的数据是那个类来操作。
ThreadClient
HashMap<key,value> value List<MessageInfo>
消息有两种来源:
1 自己发
2 别人发过来
唯一标示:ip+":"+port
服务器消息的转发工作
处理消息有两种情况:
1 没有聊天,我还在MainActivity
2 在聊天
原理图:
服务器:Server:public class WeiXinServer { //记录所有的客户端 publicstatic List<ThreadClient> list =new ArrayList<ThreadClient>(); /** * 启动服务 * @throws Exception */ publicvoid start() throws Exception{ final ServerSocket serverSocket = newServerSocket(8809); System.out.println(serverSocket.getLocalPort()); System.out.println(serverSocket.getInetAddress().getHostAddress()); new Thread(new Runnable() { @Override publicvoid run() { // TODO Auto-generated method stub while(true){ try{ //客户端 Socket socket = serverSocket.accept(); ThreadClient client = newThreadClient(socket); client.start(); System.out.println("ip:"+client.ip+",port:"+client.port); //通知之前已上线的人 /** *迭代所有的客户端:发送消息给每个客户端 *c:之前上线的用户 * */ for(ThreadClient c:list){ Stringmsg = "refresh@"+client.ip+"@"+client.port; c.sendMessage(msg); } //自己的上线之后,也要知道之前上线的人 //client就是自己 for(ThreadClient c:list){ Stringmsg = "refresh@"+c.ip+"@"+c.port; client.sendMessage(msg); } list.add(client); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); } catch (Exception e) { //TODO Auto-generated catch block e.printStackTrace(); } } publicstatic void main(String[] args) { // TODO Auto-generated method stub start(); }}ThreadClient:
public class ThreadClient extends Thread { //ip地址 publicString ip; //端口号 publicint port; //客户端套接字 publicSocket socket; //输入流 publicInputStream is; //输出流 publicOutputStream os; publicPrintWriter pw; publicBufferedReader br; publicThreadClient(Socket socket) { super(); try { this.socket= socket; this.ip= socket.getInetAddress().getHostAddress(); this.port= socket.getPort(); this.is= socket.getInputStream(); this.br= new BufferedReader(new InputStreamReader(is)); this.os= socket.getOutputStream(); this.pw= new PrintWriter(os); } catch (Exception e) { //TODO Auto-generated catch block e.printStackTrace(); } } //发送消息 publicvoid sendMessage(String msg){ pw.println(msg); pw.flush(); } @Override publicvoid run() { // TODO Auto-generated method stub super.run(); while(true){ try{ String message = br.readLine(); if(message != null){ System.out.println("服务器得到消息"+message); StringTokenizertoken = new StringTokenizer(message, "@"); Stringcmd = token.nextToken(); //消息 if("text".equals(cmd)){ String ip1 = token.nextToken(); int port1 =Integer.parseInt(token.nextToken()); String content = token.nextToken(); //查找要发送的目标 //迭代服务器所有的Socket List<ThreadClient> list =WeiXinServer.list; for(ThreadClient client:list){ if(ip1.equals(client.ip)&& port1==client.port){ //拼接消息text@ip@port@content String msg ="text@"+ip+"@"+port+"@"+content; client.sendMessage(msg); System.out.println(msg); break; } } } } }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
客户端:Adapter:
public class MyChatMessageAdapter extendsBaseAdapter { privateContext context; privateList<MessageInfo> infos; privateLayoutInflater mInflater; publicMyChatMessageAdapter(Context context, List<MessageInfo> infos) { super(); this.context = context; this.infos = infos; mInflater = LayoutInflater.from(context); } @Override publicint getCount() { // TODO Auto-generated method stub return infos.size(); } @Override publicObject getItem(int position) { // TODO Auto-generated method stub return infos.get(position); } @Override publiclong getItemId(int position) { // TODO Auto-generated method stub return position; } @Override publicView getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View view = null; ViewHolder holder = null; if(convertView != null){ view= convertView; holder= (ViewHolder) view.getTag(); }else{ view= mInflater.inflate(R.layout.chating_item, null); holder= new ViewHolder(); holder.tv_message= (TextView) view.findViewById(R.id.tv_message); view.setTag(holder); } MessageInfo info = infos.get(position); holder.tv_message.setText(info.content); return view; } privateclass ViewHolder{ TextView tv_message; }}public class MyUserAdapter extends BaseAdapter{ privateList<UserInfo> infos; privateContext context; privateLayoutInflater mInflater; publicMyUserAdapter(List<UserInfo> infos, Context context) { super(); this.infos = infos; this.context = context; mInflater = LayoutInflater.from(context); } @Override publicint getCount() { // TODO Auto-generated method stub return infos.size(); } @Override publicObject getItem(int position) { // TODO Auto-generated method stub return infos.get(position); } @Override publiclong getItemId(int position) { // TODO Auto-generated method stub return position; } @Override publicView getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub View view = null; ViewHolder holder = null; if(convertView != null){ view= convertView; holder= (ViewHolder) view.getTag(); }else{ view= mInflater.inflate(R.layout.user_item, null); holder= new ViewHolder(); holder.tv_ip= (TextView) view.findViewById(R.id.tv_ip); holder.tv_port= (TextView) view.findViewById(R.id.tv_port); holder.tv_isnew= (TextView) view.findViewById(R.id.tv_isnew); view.setTag(holder); } //得到数据 UserInfo info = infos.get(position); holder.tv_ip.setText(info.ip); holder.tv_port.setText(info.port+""); if(info.isNew){ holder.tv_isnew.setVisibility(View.VISIBLE); }else{ holder.tv_isnew.setVisibility(View.INVISIBLE); } return view; } privateclass ViewHolder{ TextView tv_ip; TextView tv_port; TextView tv_isnew; }}Client:
public class ThreadClient extends Thread { //记录用户的信息 publicList<UserInfo> userInfos = new ArrayList<UserInfo>(); //存放所有的消息 publicHashMap<String,List<MessageInfo>> messages = new HashMap<String,List<MessageInfo>>(); publicSocket socket; publicString ip; publicint port; publicInputStream is; publicOutputStream os; publicPrintWriter pw; publicBufferedReader br; publicstatic Context context; privatestatic ThreadClient threadClient; public static ThreadClient getThreadClient(Context c){ context = c; if(threadClient == null){ try{ //创建Socket Socket socket = newSocket("192.168.43.143", 8809); threadClient = new ThreadClient(socket); threadClient.start(); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return threadClient; } privateThreadClient(Socket socket) { super(); this.socket = socket; try { this.ip= socket.getInetAddress().getHostAddress(); this.port= socket.getPort(); this.is= socket.getInputStream(); this.br= new BufferedReader(new InputStreamReader(is)); this.os= socket.getOutputStream(); this.pw= new PrintWriter(os); } catch (Exception e) { //TODO Auto-generated catch block e.printStackTrace(); } } //得到指定用户的信息 publicList<MessageInfo> getMessages(String key){ return messages.get(key); } @Override publicvoid run() { // TODO Auto-generated method stub super.run(); while(true){ try{ String message = br.readLine(); if(message != null){ StringTokenizertoken = new StringTokenizer(message, "@"); Stringcmd = token.nextToken(); Stringip1 = token.nextToken(); int port1 = Integer.parseInt(token.nextToken()); //刷新用户的列表 if("refresh".equals(cmd)){ Log.i("i","ip:"+ip1+",port:"+port1); //刷新列表界面 //发广播 boolean flag =this.ip.equals(ip1)&&this.port == port1; Log.i("i","flag:"+flag); if(!flag){//如果不是自己给自己发送的 userInfos.add(newUserInfo(ip1, port1)); Intentintent = new Intent(); intent.setAction("com.action.jky.MainActivity"); context.sendBroadcast(intent); Log.i("i","已经发出广播"); //当有新的用户上线就创建一个新的消息集合 HashMap<String,List<MessageInfo>> messages = threadClient.messages; messages.put(ip1+":"+port1,new ArrayList<MessageInfo>()); } }elseif("text".equals(cmd)){ Log.i("i","得到服务器的消息:"+cmd); //1 在MainActivity //2 在ChatingActivity String name =context.getClass().getName(); Log.i("i", "全类名"+name); //消息的内容 String content = token.nextToken(); if("com.huaao.weixin.ui.MainActivity".equals(name)){ Intentintent = new Intent(); intent.setAction("com.huaao.weixin.ui.MainActivity"); intent.putExtra("ip",ip1); intent.putExtra("port",port1); intent.putExtra("content",content); context.sendBroadcast(intent); }elseif("com.huaao.weixin.ui.ChatingActivity".equals(name)){ Intentintent = new Intent(); intent.setAction("com.huaao.weixin.ui.ChatingActivity"); intent.putExtra("ip",ip1); intent.putExtra("port",port1); intent.putExtra("content",content); context.sendBroadcast(intent); } } } }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //发送消息 目标对象 消息内容 publicvoid sendMessage(String ip,int port,String message){ //找到目标对象:告诉服务消息要转发的ip 和 port //text@ip@port@message String msg ="text@"+ip+"@"+port+"@"+message; pw.println(msg); pw.flush(); }}Domain:
public class MessageInfo { publicString content; publicMessageInfo(String content) { super(); this.content = content; } }public class UserInfo { publicString ip; publicint port; publicboolean isNew;//是否有新消息 publicUserInfo(String ip, int port) { super(); this.ip = ip; this.port = port; } }Ui:
public class ChatingActivity extendsActivity { privateTextView tv_title; privateListView lv_message; privateEditText et_message; privateThreadClient threadClient; privateString ip; privateint port; privateString key; privateMyChatMessageAdapter adapter; @Override protectedvoid onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.chating); tv_title = (TextView)findViewById(R.id.tv_title); lv_message = (ListView)findViewById(R.id.lv_message); et_message = (EditText)findViewById(R.id.et_message); threadClient =ThreadClient.getThreadClient(this); Intent intent = getIntent(); ip =intent.getStringExtra("ip"); port =intent.getIntExtra("port", 0); key = ip+":"+port; tv_title.setText(key); List<MessageInfo> infos =threadClient.getMessages(key); adapter = new MyChatMessageAdapter(this,infos); lv_message.setAdapter(adapter); IntentFilter filter = new IntentFilter(); filter.addAction("com.huaao.weixin.ui.ChatingActivity"); registerReceiver(new MyReceiver(),filter); } privateclass MyReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context,Intent intent) { //TODO Auto-generated method stub //得到消息 //把消息添加消息集合 //刷新界面 Stringip = intent.getStringExtra("ip"); intport = intent.getIntExtra("port", 0); Stringcontent = intent.getStringExtra("content"); //把消息添加到消息集合 List<MessageInfo>messages = threadClient.getMessages(ip+":"+port); messages.add(newMessageInfo(content)); adapter.notifyDataSetChanged(); } } publicvoid send(View v){ //得到消息 //发送消息 //把消息添加到消息集合 String message =et_message.getText().toString(); threadClient.sendMessage(ip, port,message); List<MessageInfo> messages =threadClient.getMessages(key); messages.add(new MessageInfo(message)); //刷新消息界面 adapter.notifyDataSetChanged(); }}public class MainActivity extends Activity{ private ListView lv_user; privateMyUserAdapter adapter; privateMyRefreshBroadCastReceiver receiver; privateThreadClient threadClient; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); threadClient = ThreadClient.getThreadClient(this); lv_user = (ListView) findViewById(R.id.lv_user); List<UserInfo> userInfos = threadClient.userInfos; adapter = new MyUserAdapter(userInfos, this); lv_user.setAdapter(adapter); //订阅广播 receiver = new MyRefreshBroadCastReceiver(); IntentFilter filter = new IntentFilter(); //用户上线 filter.addAction("com.action.jky.MainActivity"); //有新消息 filter.addAction("com.huaao.weixin.ui.MainActivity"); registerReceiver(receiver, filter); //设置条目的点击事件 lv_user.setOnItemClickListener(new MyOnItemClickListener()); } private class MyOnItemClickListener implements OnItemClickListener{ @Override public voidonItemClick(AdapterView<?> parent, View view, int position, long id) { //TODO Auto-generated method stub UserInfoinfo = (UserInfo) adapter.getItem(position); Intentintent = new Intent(getApplicationContext(),ChatingActivity.class); intent.putExtra("ip",info.ip); intent.putExtra("port",info.port); startActivity(intent); //把新消息隐藏 view.findViewById(R.id.tv_isnew).setVisibility(View.INVISIBLE); } } private class MyRefreshBroadCastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context,Intent intent) { //TODO Auto-generated method stub Stringaction = intent.getAction(); //用户上线 if("com.action.jky.MainActivity".equals(action)){ adapter.notifyDataSetChanged(); Log.i("i","得到通知刷新显示"); }elseif("com.huaao.weixin.ui.MainActivity".equals(action)){ Log.i("i","有广播到来。。可以出现有新消息"); //有新消息 String ip =intent.getStringExtra("ip"); int port =intent.getIntExtra("port", 0); String content =intent.getStringExtra("content"); //把消息添加到消息集合 List<MessageInfo> messages =threadClient.getMessages(ip+":"+port); messages.add(new MessageInfo(content)); //修改用户有新消息 List<UserInfo> userInfos =threadClient.userInfos; for(UserInfo info:userInfos){ if(ip.equals(info.ip)&& port == info.port){ info.isNew = true; break; } } adapter.notifyDataSetChanged(); } } } }
0 0
- ym——Android从零开始(27)(山寨版微信-下)(新)
- ym——Android从零开始(27)(山寨版微信-上)(新)
- ym——Android从零开始(18)(多线程下载-下)(新)
- ym——Android从零开始(7)(SQLite数据库)(新)
- ym——Android从零开始(9)(ContentProvider内容提供者)(新)
- ym——Android从零开始(17)(多线程下载-上)(新)
- ym——Android从零开始(20)(TabHost+ExpandableListView)(新)
- ym——Android从零开始(21)(自定义控件)(新)
- ym——Android从零开始(19)(BroadcastReceiver)(新)
- ym——Android从零开始(22)(service、aidl)(新)
- ym——Android从零开始(23)(Notification+ Animation)(新)
- ym——Android从零开始(24)(多媒体播放器)(新)
- ym——Android从零开始(29)(Bluetooth2.0+4.0)(新)
- ym——Android从零开始(30)(WIFI、传感器)(新)
- ym——Android从零开始(31)(AppWidget、快捷图标)(新)
- ym——Android从零开始(32)(WebView)(新)
- ym——Android从零开始(1)(Android体系架构及认识)(新)
- ym——Android从零开始(2)(打电话,发短信,常用布局)(新)
- How to write software Testing Weekly Status Report
- bzoj 3173 最长上升子序列
- SQL Server死锁总结
- 使用dos 写bat时,使用for循环读取文件中的内容无任何显示
- MySQL CURDATE() 函数
- ym——Android从零开始(27)(山寨版微信-下)(新)
- jQuery Mobile 特性
- 线程安全及不可变性
- 1. WebStorm-The smartest JavaScript IDE 2. Node.js 3. egret
- android -- 小问题 关于ListView设置了OnScrollListener之后onScrollStateChanged()和onScroll方法监听不到的问题
- Git warning push.default is unset
- 代码规范
- 用Javascript实现查看CSS属性使用频率的功能
- uva 10375 (唯一分解定理+筛素数)