以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 
+   " \n " ));
        }
    }

 

 

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 
+   " \n " ));
                }
                
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(
" 监听请求时出错:\r\n "   +  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(
" 接收的数据出错:\r\n{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( " \n " "   " ));

            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( " \n " )) {
                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 
+=   " \n " ;
                        }
                        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 ;
    }
}

 

 五、运行效果

 

 

 

 

  代码下载

  出处:http://www.cnblogs.com/GoodHelper/archive/2011/07/08/android_socket_chart.html

  欢迎转载,但需保留版权!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值