ym——Android从零开始(27)(山寨版微信-下)(新)

来源:互联网 发布:社会发展统计数据库 编辑:程序博客网 时间:2024/05/29 04:50

转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!


山寨版微信(下)

昨天 我们完成 上线列表刷新。

聊天:

消息:

用户发送:

只需要显示客户端的消息。

一个人可以和多个人聊天。

聊天的内容存放在哪里?数据库  内存  文件

你的数据是那个类来操作。

ThreadClient

HashMap<key,value>  value List<MessageInfo>

消息有两种来源:

自己发

别人发过来

唯一标示:ip+":"+port

服务器消息的转发工作

处理消息有两种情况:

没有聊天,我还在MainActivity

在聊天

原理图:

1.png

服务器:

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
原创粉丝点击