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 ;
        }
    }

     五、运行效果

     

      代码下载

  • 相关阅读:
    php mysqli 查询个门店数据(面向对象)
    php 上锁 概述
    php 小程序渠道推广,转发
    php 微信公众号获取用户信息
    php 小程序获取用户信息
    php 生成小程序二维码
    1、收集日志至指定主题
    hihoCoder 网络流四·最小路径覆盖
    hihocoder1393 网络流三·二分图多重匹配
    hihocoder1398 网络流五之最大权闭合子图
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/3806475.html
Copyright © 2011-2022 走看看