zoukankan      html  css  js  c++  java
  • 以C#编写的Socket服务器的Android手机聊天室Demo

    内容摘要

       1.程序架构

       2.通信协议

       3.服务器源代码

       4.客户端源代码

       5.运行效果

      一、程序架构

      在开发一个聊天室程序时,我们可以使用Socket、Remoting、WCF这些具有双向通信的协议或框架。而现在,我正要实现一个C#语言作为服务器 端、Android作为客户端的聊天室。由于服务器端和客户端不是同一语言(C#和java),所有我选择了Socket作为通信协议。

      图1.1所示,我们可以看出:android手机客户端A向服务器端发送消息,服务器端收到消息后,又把消息推送到android手机客户端B。

     图1.1

      二、通信协议

    我们知道,在C#语言中使用Socket技术需要“四部曲”,即“Bind”,“Listen”,“Accept”,“Receive”。然而 Socket编程不像WCF那样面向对象。而且对应每个请求都用同一种方式处理。作为习惯面向对象编程的我来说,编写一个传统的Socket程序很不爽。 绞尽脑汁,我们将数据传输的格式改为json(JavaScript Object Notation 是一种轻量级的数据交换格式),面对对象的问题就解决了。

       假设程序的服务契约有两个方法:“登陆”和“发送消息”。调用登陆的方法,就传送方法名(Method Name)为“Logon”的json数据;调用发送消息的方法,就传送方法名为“Send”的json数据。返回的数据中也使用json格式,这样在 android客户端中也能知道是哪个方法的返回值了。

      三、服务器源代码

     首先需要编写一个处理客户端消息的接口:IResponseManager。

         public   interface  IResponseManager
        {
             void  Write(Socket sender, IList < Socket >  cliens, IDictionary < string ,  object >  param);
        }

    其次,我们知道,换了是WCF编程的话,就需要在服务契约中写两个方法:“登陆”和“发送消息”。由于这里是Socket编程,我们实现之前写的IResponseManager接口,一个实现作为“登陆”的方法,另一个实现作为“发送消息”的方法。

    public   class  LogonResponseManager : IResponseManager
        {
             public   void  Write(System.Net.Sockets.Socket sender, IList < System.Net.Sockets.Socket >  cliens, IDictionary < string ,  object >  param)
            {
                Console.WriteLine( " 客户端({0})登陆 " , sender.Handle);
                var response  =   new  SocketResponse
                {
                    Method  =   " Logon " ,
                    DateTime  =  DateTime.Now.ToString( " yyyy-MM-dd HH:mm:ss " ),
                    Result  =   new  { UserName  =  param[ " UserName " ].ToString() }
                };

                JavaScriptSerializer jss  =   new  JavaScriptSerializer();
                 string  context  =  jss.Serialize(response);
                Console.WriteLine( " 登陆发送的数据为:{0} " , context);
                sender.Send(Encoding.UTF8.GetBytes(context  +   " " ));
            }
        }
    public   class  SendResponseManager : IResponseManager
        {
             public   void  Write(System.Net.Sockets.Socket sender, IList < System.Net.Sockets.Socket >  cliens, IDictionary < string ,  object >  param)
            {
                Console.WriteLine( " 客户端({0})发送消息 " , sender.Handle);
                var msgList  =  param[ " Message " ]  as  IEnumerable < object > ;
                 if  (msgList  ==   null )
                {
                     return ;
                }

                var response  =   new  SocketResponse
                {
                    Method  =   " Send " ,
                    DateTime  =  DateTime.Now.ToString( " yyyy-MM-dd HH:mm:ss " ),
                    Result  =   new
                    { 
                        UserName  =  param[ " UserName " ].ToString(),
                        Message  =  msgList.Select(s  =>  s.ToString()).ToArray() 
                    }
                };

                JavaScriptSerializer jss  =   new  JavaScriptSerializer();
                 string  context  =  jss.Serialize(response);
                Console.WriteLine( " 消息发送的数据为:{0} " , context);

                Parallel.ForEach(cliens, (item)  =>
                {
                     try
                    {
                        item.Send(Encoding.UTF8.GetBytes(context  +   " " ));
                    }
                     catch  { };
                });
            }
        }

    最后在Socket程序中使用反射加“策略模式”调用这两个接口实现类。

                var typeName  =   " SocketServer. "   +  request.Method  +   " ResponseManager, SocketServer " ;
                Console.WriteLine( " 反射类名为: "   +  typeName);

                Type type  =  Type.GetType(typeName);
                 if  (type  ==   null )
                {
                     return ;
                }

                var manager  =  Activator.CreateInstance(type)  as  IResponseManager;
                manager.Write(sender,  this .socketClientSesson.Select(s  =>  s.Key).ToList(),
                    request.Param  as  IDictionary < string ,  object > );

    完整的Socket服务器代码如下:

    public   class  SocketHost
        {
             private  IDictionary < Socket,  byte [] >  socketClientSesson  =   new  Dictionary < Socket,  byte [] > ();

             public   int  Port {  get ;  set ; }

             public   void  Start()
            {
                var socketThread  =   new  Thread(()  =>
                {
                    Socket socket  =   new  Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPEndPoint iep  =   new  IPEndPoint(IPAddress.Any,  this .Port);

                     // 绑定到通道上
                    socket.Bind(iep);

                     // 侦听
                    socket.Listen( 6 );

                     // 通过异步来处理
                    socket.BeginAccept( new  AsyncCallback(Accept), socket);

                });

                socketThread.Start();

                Console.WriteLine( " 服务器已启动 " );
            }

             private   void  Accept(IAsyncResult ia)
            {
                Socket socket  =  ia.AsyncState  as  Socket;
                var client  =  socket.EndAccept(ia);

                socket.BeginAccept( new  AsyncCallback(Accept), socket);

                 byte [] buf  =   new   byte [ 1024 ];
                 this .socketClientSesson.Add(client, buf);

                 try
                {
                    client.BeginReceive(buf,  0 , buf.Length, SocketFlags.None,  new  AsyncCallback(Receive), client);
                     string  sessionId  =  client.Handle.ToString();
                    Console.WriteLine( " 客户端({0})已连接 " , sessionId);
                }
                 catch  (Exception ex)
                {
                    Console.WriteLine( " 监听请求时出错: "   +  ex.ToString());
                }
            }

             private   void  Receive(IAsyncResult ia)
            {
                var client  =  ia.AsyncState  as  Socket;

                 if  (client  ==   null   ||   ! this .socketClientSesson.ContainsKey(client))
                {
                     return ;
                }

                 int  count  =  client.EndReceive(ia);

                 byte [] buf  =   this .socketClientSesson[client];

                 if  (count  >   0 )
                {
                     try
                    {
                        client.BeginReceive(buf,  0 , buf.Length, SocketFlags.None,  new  AsyncCallback(Receive), client);
                         string  context  =  Encoding.UTF8.GetString(buf,  0 , count);
                        Console.WriteLine( " 接收的数据为: " , context);

                         this .Response(client, context);
                    }
                     catch  (Exception ex)
                    {
                        Console.WriteLine( " 接收的数据出错: {0} " , ex.ToString());
                    }
                }
                 else
                {
                     try
                    {
                         string  sessionId  =  client.Handle.ToString();
                        client.Disconnect( true );
                         this .socketClientSesson.Remove(client);
                        Console.WriteLine( " 客户端({0})已断开 " , sessionId);
                    }
                     catch  (Exception ex)
                    {
                        Console.WriteLine( " 客户端已断开出错 "   +  ex.ToString());
                    }
                }
            }

             private   void  Response(Socket sender,  string  context)
            {
                SocketRequest request  =   null ;
                JavaScriptSerializer jss  =   new  JavaScriptSerializer();
                request  =  jss.Deserialize(context,  typeof (SocketRequest))  as  SocketRequest;

                 if  (request  ==   null )
                {
                     return ;
                }

                var typeName  =   " SocketServer. "   +  request.Method  +   " ResponseManager, SocketServer " ;
                Console.WriteLine( " 反射类名为: "   +  typeName);

                Type type  =  Type.GetType(typeName);
                 if  (type  ==   null )
                {
                     return ;
                }

                var manager  =  Activator.CreateInstance(type)  as  IResponseManager;
                manager.Write(sender,  this .socketClientSesson.Select(s  =>  s.Key).ToList(),
                    request.Param  as  IDictionary < string ,  object > );
            }
        }

    最后,json数据传输的实体对象为:

       [Serializable]
         public   class  SocketRequest
        {
             public   string  Method {  get ;  set ; }

             public   string  DateTime {  get ;  set ; }

             public   object  Param {  get ;  set ; }
        }
        [Serializable]
         public   class  SocketResponse
        {
             public   string  Method {  get ;  set ; }

             public   string  DateTime {  get ;  set ; }

             public   object  Result {  get ;  set ; }
        }

     四、客户端源代码

    1.布局文件

    logon.xml:

    <? xml version="1.0" encoding="utf-8" ?>
    < LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
        android:orientation ="vertical"  android:layout_width ="fill_parent"
        android:layout_height ="fill_parent"  android:background ="@drawable/background" >

         < LinearLayout  android:orientation ="vertical"
            android:layout_width ="fill_parent"  android:layout_height ="60dip"
            android:background ="@drawable/logon"   />

         < LinearLayout  android:orientation ="vertical"
            android:layout_width ="fill_parent"  android:layout_height ="fill_parent"
            android:paddingLeft ="10dp"  android:paddingRight ="10dp" >

             < View  android:layout_width ="fill_parent"  android:layout_height ="20dip"   />

             < TextView  android:id ="@+id/feedback_title"  android:textColor ="#FFFFFF"
                android:layout_width ="fill_parent"  android:layout_height ="wrap_content"
                android:text ="用户名:"   />
             < EditText  android:id ="@+id/edtUserName"  android:layout_width ="fill_parent"
                android:layout_height ="wrap_content"   />

             < View  android:layout_width ="fill_parent"  android:layout_height ="2dip"
                android:background ="#FF909090"   />

             < TextView  android:layout_width ="fill_parent"
                android:textColor ="#FFFFFF"  android:layout_height ="wrap_content"
                android:text ="IP地址:"   />
             < EditText  android:id ="@+id/edtIp"  android:layout_width ="fill_parent"
                android:layout_height ="wrap_content"  android:digits ="1234567890."  
                android:text ="192.168.1.101" />

             < View  android:layout_width ="fill_parent"  android:layout_height ="2dip"
                android:background ="#FF909090"   />

             < TextView  android:layout_width ="fill_parent"
                android:textColor ="#FFFFFF"  android:layout_height ="wrap_content"
                android:text ="端口号:"   />
             < EditText  android:id ="@+id/edtPort"  android:layout_width ="fill_parent"
                android:layout_height ="wrap_content"  android:inputType ="number"
                android:numeric ="integer"  android:text ="1234" />

             < LinearLayout  android:orientation ="horizontal"
                android:layout_width ="fill_parent"  android:layout_height ="wrap_content"
                android:layout_marginTop ="10dp" >
             </ LinearLayout >
             < RelativeLayout  android:layout_width ="fill_parent"
                android:layout_height ="fill_parent" >
                 < View  android:id ="@+id/feedback_content"  android:layout_width ="fill_parent"
                    android:layout_height ="fill_parent"  android:maxEms ="10"
                    android:minEms ="10"  android:gravity ="top"
                    android:layout_marginBottom ="50dip"   />
                 < Button  android:id ="@+id/btnLogon"  android:layout_width ="fill_parent"
                    android:layout_height ="50dp"  android:text ="登陆"  android:textSize ="19dp"
                    android:layout_gravity ="center_horizontal"
                    android:layout_alignParentBottom ="true"   />
             </ RelativeLayout >
         </ LinearLayout >
    </ LinearLayout >

    main.xml:

    <? xml version="1.0" encoding="utf-8" ?>
    < LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
        android:orientation ="vertical"  android:layout_width ="fill_parent"
        android:layout_height ="fill_parent"  android:background ="@drawable/background" >

         < ListView  android:layout_width ="fill_parent"
            android:layout_height ="wrap_content"  android:id ="@+id/ltvMessage" >
         </ ListView >

         < RelativeLayout  android:layout_width ="fill_parent"
            android:layout_height ="wrap_content" >

             < EditText  android:layout_width ="fill_parent"
                android:layout_height ="wrap_content"  android:id ="@+id/edtMessage"
                android:hint ="请输入消息"  android:layout_alignTop ="@+id/btnSend"
                android:layout_toLeftOf ="@+id/btnSend"   />

             < Button  android:text ="SEND"  android:id ="@+id/btnSend"
                android:layout_height ="wrap_content"  android:layout_width ="wrap_content"
                android:layout_alignParentRight ="true"   />
         </ RelativeLayout >

    </ LinearLayout >

    listview_item.xml:

    <? xml version="1.0" encoding="utf-8" ?>
    < LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
        android:layout_width ="fill_parent"  android:layout_height ="wrap_content"
        android:orientation ="vertical"  android:paddingBottom ="3dip"
        android:paddingLeft ="10dip" >

         < TextView  android:layout_height ="wrap_content"
            android:layout_width ="fill_parent"  android:id ="@+id/itmMessage"
            android:textSize ="20dip" >
         </ TextView >

         < LinearLayout  android:layout_width ="fill_parent"
            android:orientation ="horizontal"  android:layout_height ="20dip" >
             < TextView  android:layout_height ="fill_parent"
                android:layout_width ="100dip"  android:id ="@+id/itmUserName"   >
             </ TextView >

             < TextView  android:layout_height ="fill_parent"
                android:layout_width ="200dip"  android:id ="@+id/itmTime"   >
             </ TextView >

         </ LinearLayout >

    </ LinearLayout >

    SocketClient:

    package  ld.socket;

    import  java.io.BufferedReader;
    import  java.io.BufferedWriter;
    import  java.io.IOException;
    import  java.io.InputStreamReader;
    import  java.io.OutputStreamWriter;
    import  java.net.Socket;
    import  java.net.UnknownHostException;
    import  java.text.SimpleDateFormat;
    import  java.util.Date;
    import  java.util.HashMap;
    import  java.util.Map;

    import  org.json.JSONArray;
    import  org.json.JSONException;
    import  org.json.JSONObject;

    import  android.os.Handler;
    import  android.os.Message;
    import  android.util.Log;

    public   class  SocketClient {

         private   static  Socket client;

         private   static  SocketClient instance  =   null ;

         public   static  SocketClient getInstance() {
             if  (instance  ==   null ) {

                 synchronized  (ChartInfo. class ) {
                     if  (instance  ==   null ) {
                         try  {
                            ChartInfo chartInfo  =  ChartInfo.getInstance();
                            client  =   new  Socket(chartInfo.getIp(), chartInfo
                                    .getPort());
                            instance  =   new  SocketClient();
                        }  catch  (UnknownHostException e) {
                             //  TODO Auto-generated catch block
                        }  catch  (IOException e) {
                             //  TODO Auto-generated catch block
                        }
                    }
                }
            }
             return  instance;
        }

         private  SocketClient() {
             this .initMap();
             this .startThread();
        }

         private   void  initMap() {
             this .handlerMap  =   new  HashMap < String, Handler > ();
        }

         public   void  close() {
             try  {
                client.close();
            }  catch  (IOException e) {
                 //  TODO Auto-generated catch block
                 // e.printStackTrace();
            }
            instance  =   null ;
        }
        
         private   void  startThread() {
            Thread thread  =   new  Thread() {
                @Override
                 public   void  run() {

                     while  ( true ) {
                         if  (client  ==   null   ||   ! client.isConnected()) {
                             continue ;
                        }

                        BufferedReader reader;
                         try  {
                            reader  =   new  BufferedReader( new  InputStreamReader(
                                    client.getInputStream()));
                            String line  =  reader.readLine();
                            Log.d( " initSocket " ,  " line: "   +  line);
                             if  (line.equals( "" )) {
                                 continue ;
                            }

                            JSONObject json  =   new  JSONObject(line);
                            String method  =  json.getString( " Method " );
                            Log.d( " initSocket " ,  " method: "   +  method);
                             if  (method.equals( "" )
                                     ||   ! handlerMap.containsKey(method)) {
                                Log.d( " initSocket " ,  " handlerMap not method " );
                                 continue ;
                            }

                            Handler handler  =  handlerMap.get(method);
                             if  (handler  ==   null ) {
                                Log.d( " initSocket " ,  " handler is null " );
                                 continue ;
                            }
                            Log.d( " initSocket " ,  " handler: "   +  method);
                            Object obj  =  json.getJSONObject( " Result " );
                            Log.d( " initSocket " ,  " Result: "   +  obj);
                            Message msg  =   new  Message();
                            msg.obj  =  obj;
                            handler.sendMessage(msg);

                        }  catch  (IOException e) {

                        }  catch  (JSONException e) {

                        }
                    }
                }
            };
            thread.start();
        }

         private  Map < String, Handler >  handlerMap;

         public   void  putHandler(String methodnName, Handler handler) {
             this .removeHandler(methodnName);
             this .handlerMap.put(methodnName, handler);
        }

         public   void  removeHandler(String methodnName) {
             if  ( this .handlerMap.containsKey(methodnName)) {
                 this .handlerMap.remove(methodnName);
            }
        }

         public   void  logon(String userName) {
            Log.d( " initSocket " ,  " logon " );
             try  {
                OutputStreamWriter osw  =   new  OutputStreamWriter(client
                        .getOutputStream());

                BufferedWriter writer  =   new  BufferedWriter(osw);

                JSONObject param  =   new  JSONObject();
                param.put( " UserName " , userName.replace( " " ,  "   " ));

                JSONObject json  =   this .getJSONData( " Logon " , param);

                writer.write(json.toString());
                writer.flush();
            }  catch  (IOException e) {
                 //  TODO Auto-generated catch block
                e.printStackTrace();
            }  catch  (JSONException e) {
                 //  TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

         public   void  sendMessage(String message) {
            Log.d( " initSocket " ,  " Send " );
             try  {
                OutputStreamWriter osw  =   new  OutputStreamWriter(client
                        .getOutputStream());

                BufferedWriter writer  =   new  BufferedWriter(osw);

                JSONArray array  =   new  JSONArray();
                 for  (String item : message.split( " " )) {
                    array.put(item);
                }

                JSONObject param  =   new  JSONObject();
                param.put( " Message " , array);

                param.put( " UserName " , ChartInfo.getInstance().getUserName());

                JSONObject json  =   this .getJSONData( " Send " , param);

                writer.write(json.toString());
                writer.flush();
            }  catch  (IOException e) {
                 //  TODO Auto-generated catch block
                e.printStackTrace();
            }  catch  (JSONException e) {
                 //  TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

         private  JSONObject getJSONData(String methodName, JSONObject param) {
            JSONObject json  =   new  JSONObject();
             try  {
                json.put( " Method " , methodName);
                SimpleDateFormat format  =   new  SimpleDateFormat(
                         " yyyy-MM-dd HH:mm:ss " );
                json.put( " DateTime " , format.format( new  Date()));
                json.put( " Param " , param);
                 return  json;
            }  catch  (JSONException e) {
                 return   null ;
            }
        }
    }

    LogonActivity:

    package  ld.socket;

    import  org.json.JSONException;
    import  org.json.JSONObject;

    import  android.app.Activity;
    import  android.app.AlertDialog;
    import  android.content.ComponentName;
    import  android.content.DialogInterface;
    import  android.content.Intent;
    import  android.os.Bundle;
    import  android.os.Handler;
    import  android.os.Message;
    import  android.util.Log;
    import  android.view.KeyEvent;
    import  android.view.View;
    import  android.view.View.OnClickListener;
    import  android.widget.Button;
    import  android.widget.EditText;

    public   class  LogonActivity  extends  Activity {

         private  EditText edtUserName;
         private  EditText edtIp;
         private  EditText edtPort;

         private  Button btnLogon;

        @Override
         protected   void  onCreate(Bundle savedInstanceState) {
             //  TODO Auto-generated method stub
             super .onCreate(savedInstanceState);

            setContentView(R.layout.logon);

             this .initViews();
        }

         private   void  initViews() {
             this .edtUserName  =  (EditText)  this .findViewById(R.id.edtUserName);
             this .edtIp  =  (EditText)  this .findViewById(R.id.edtIp);
             this .edtPort  =  (EditText)  this .findViewById(R.id.edtPort);

             this .btnLogon  =  (Button)  this .findViewById(R.id.btnLogon);
             this .btnLogon.setOnClickListener( new  OnClickListener() {

                @Override
                 public   void  onClick(View v) {
                     //  TODO Auto-generated method stub

                     //  showAlert(edtUserName.getText().toString());
                     if  (edtUserName.getText().toString().equals( "" )) {
                        showDialog( " 请输入用户名 " );
                         return ;
                    }

                     if  (edtIp.getText().toString().equals( "" )) {
                        showDialog( " 请输入IP地址 " );
                         return ;
                    }

                     if  (edtPort.getText().toString().equals( "" )) {
                        showDialog( " 请输入端口号 " );
                         return ;
                    }

                     int  port  =  Integer.parseInt(edtPort.getText().toString());
                    ChartInfo chartInfo  =  ChartInfo.getInstance();
                    chartInfo.setIp(edtIp.getText().toString());
                    chartInfo.setPort(port);
                    SocketClient proxy  =  SocketClient.getInstance();

                     if  (proxy  ==   null ) {
                        showDialog( " 未接入互联网 " );
                        setWireless();
                         return ;
                    }

                    proxy.putHandler( " Logon " ,  new  Handler() {
                        @Override
                         public   void  handleMessage(Message msg) {

                            SocketClient proxy  =  SocketClient.getInstance();
                            proxy.removeHandler( " Logon " );
                            Log.d( " initSocket " ,  " handleMessage " );
                             if  (msg  ==   null   ||  msg.obj  ==   null ) {
                                 return ;
                            }

                            JSONObject json  =  (JSONObject) msg.obj;
                             try  {
                                String userName  =  json.getString( " UserName " );
                                Log.d( " initSocket " ,  " userName: "   +  userName);
                                ChartInfo.getInstance().setUserName(userName);
                                Intent itt  =   new  Intent();
                                itt
                                        .setClass(LogonActivity. this ,
                                                MainActivity. class );
                                LogonActivity. this .startActivity(itt);
                            }  catch  (JSONException e) {
                                 //  TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    });
                    proxy.logon(edtUserName.getText().toString());
                }
            });
        }

         private   void  setWireless() {
            Intent mIntent  =   new  Intent( " / " );
            ComponentName comp  =   new  ComponentName( " com.android.settings " ,
                     " com.android.settings.WirelessSettings " );
            mIntent.setComponent(comp);
            mIntent.setAction( " android.intent.action.VIEW " );
            startActivityForResult(mIntent,  0 );
        }

         private   void  showDialog(String mess) {
             new  AlertDialog.Builder( this ).setTitle( " 信息 " ).setMessage(mess)
                    .setNegativeButton( " 确定 " ,  new  DialogInterface.OnClickListener() {
                         public   void  onClick(DialogInterface dialog,  int  which) {
                        }
                    }).show();
        }

        @Override
         public   boolean  onKeyDown( int  keyCode, KeyEvent event) {

             if  (keyCode  ==  KeyEvent.KEYCODE_BACK  &&  event.getRepeatCount()  ==   0 ) {

                AlertDialog alertDialog  =   new  AlertDialog.Builder(
                        LogonActivity. this ).setTitle( " 退出程序 " ).setMessage( " 是否退出程序 " )
                        .setPositiveButton( " 确定 " ,
                                 new  DialogInterface.OnClickListener() {

                                     public   void  onClick(DialogInterface dialog,
                                             int  which) {
                                        LogonActivity. this .finish();
                                    }

                                }).setNegativeButton( " 取消 " ,

                         new  DialogInterface.OnClickListener() {
                             public   void  onClick(DialogInterface dialog,  int  which) {
                                 return ;
                            }
                        }).create();  //  创建对话框

                alertDialog.show();  //  显示对话框

                 return   false ;

            }

             return   false ;
        }

        @Override
         protected   void  onDestroy() {
             //  TODO Auto-generated method stub
             super .onDestroy();
            SocketClient proxy  =  SocketClient.getInstance();
             if  (proxy  !=   null ) {
                proxy.close();
            }
        }

    }

    MainActivity:

    package  ld.socket;

    import  org.json.JSONException;
    import  org.json.JSONObject;

    import  android.app.Activity;
    import  android.app.AlertDialog;
    import  android.content.DialogInterface;
    import  android.os.Bundle;
    import  android.os.Handler;
    import  android.os.Message;
    import  android.util.Log;
    import  android.view.KeyEvent;
    import  android.view.View;
    import  android.view.WindowManager;
    import  android.view.View.OnClickListener;
    import  android.widget.Button;
    import  android.widget.EditText;
    import  android.widget.ListView;

    public   class  MainActivity  extends  Activity {

         private  EditText edtMessage;

         private  Button btnSend;

         private  ListView ltvMessage;

         private  MessageAdapter adapter;

         /**  Called when the activity is first created.  */
        @Override
         public   void  onCreate(Bundle savedInstanceState) {
             super .onCreate(savedInstanceState);
            setContentView(R.layout.main);

             //  隐藏键盘
             this .getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

            Log.d( " initSocket " ,  " MessageAdapter " );
             this .adapter  =   new  MessageAdapter( this );
            Log.d( " initSocket " ,  " adapter is ok " );

             this .findThisViews();
             this .initHandler();

             this .serOnClick();

            Log.d( " initSocket " ,  " onCreate " );
        }

         private   void  findThisViews() {
             this .edtMessage  =  (EditText)  this .findViewById(R.id.edtMessage);
             this .btnSend  =  (Button)  this .findViewById(R.id.btnSend);

             this .ltvMessage  =  (ListView)  this .findViewById(R.id.ltvMessage);
             //  this.ltvMessage.setEnabled(false);
             this .ltvMessage.setAdapter( this .adapter);
        }

         private   void  initHandler() {

            Handler handler  =   new  Handler() {
                @Override
                 public   void  handleMessage(Message msg) {
                     if  (msg.obj  ==   null ) {
                        Log.d( " initSocket " ,  " handleMessage is null " );
                         return ;
                    }

                    Log.d( " initSocket " ,  " handleMessage " );
                     try  {
                        JSONObject json  =  (JSONObject) msg.obj;
                        String userName  =  json.getString( " UserName " );

                        StringBuilder sb  =   new  StringBuilder();
                         int  length  =  json.getJSONArray( " Message " ).length();
                         for  ( int  i  =   0 ; i  <  length; i ++ ) {
                            String item  =  json.getJSONArray( " Message " ).getString(i);
                             if  (item.equals( "" )) {
                                 continue ;
                            }
                             if  (length  >  i  +   1 ) {
                                Log.d( " initSocket " ,  " length: "   +  length);
                                Log.d( " initSocket " ,  " i: "   +  i);
                                Log.d( " initSocket " ,  " item: "   +  item);
                                item  +=   " " ;
                            }
                            sb.append(item);
                        }

                        MessageRecord record  =   new  MessageRecord();
                        record.setUserName(userName);
                        record.setMessage(sb.toString());

                        MainActivity. this .adapter.add(record);
                        adapter.notifyDataSetChanged();
                    }  catch  (JSONException e) {
                         //  TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
            SocketClient proxy  =  SocketClient.getInstance();
            proxy.putHandler( " Send " , handler);
        }

         private   void  serOnClick() {
             this .btnSend.setOnClickListener( new  OnClickListener() {

                @Override
                 public   void  onClick(View v) {
                     //  TODO Auto-generated method stub
                    btnSend.setEnabled( false );
                    String txt  =  edtMessage.getText().toString();
                     if  (txt.equals( "" )) {
                        btnSend.setEnabled( true );
                         return ;
                    }
                    SocketClient proxy  =  SocketClient.getInstance();
                    proxy.sendMessage(txt);
                    edtMessage.setText( "" );
                    btnSend.setEnabled( true );
                }
            });
        }

        @Override
         public   boolean  onKeyDown( int  keyCode, KeyEvent event) {

             if  (keyCode  ==  KeyEvent.KEYCODE_BACK  &&  event.getRepeatCount()  ==   0 ) {

                AlertDialog alertDialog  =   new  AlertDialog.Builder(
                        MainActivity. this ).setTitle( " 询问 " ).setMessage( " 是否注销登录? " )
                        .setPositiveButton( " 确定 " ,
                                 new  DialogInterface.OnClickListener() {

                                     public   void  onClick(DialogInterface dialog,
                                             int  which) {
                                        MainActivity. this .finish();
                                    }

                                }).setNegativeButton( " 取消 " ,

                         new  DialogInterface.OnClickListener() {
                             public   void  onClick(DialogInterface dialog,  int  which) {
                                 return ;
                            }
                        }).create();  //  创建对话框

                alertDialog.show();  //  显示对话框

                 return   false ;

            }

             return   false ;
        }
    }

     五、运行效果

     

      代码下载

  • 相关阅读:
    You are not late! You are not early!
    在同一个服务器(同一个IP)为不同域名绑定的免费SSL证书
    Vue.js Is Good, but Is It Better Than Angular or React?
    It was not possible to find any compatible framework version
    VS增加插件 Supercharger破解教程
    Git使用ssh key
    Disconnected: No supported authentication methods available (server sent: publickey)
    VS 2013打开.edmx文件时报类型转换异常
    asp.net MVC4 框架揭秘 读书笔记系列3
    asp.net MVC4 框架揭秘 读书笔记系列2
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/3806475.html
Copyright © 2011-2022 走看看