展会信息港展会大全

以C#编写的Socket服务器的Android手机聊天室Demo
来源:互联网   发布日期:2015-09-28 16:17:58   浏览:1813次  

导读: 内容摘要 1.程序架构 2.通信协议 3.服务器源代码 4.客户端源代码 5.运行效果 一、程序架构 在开发一个聊天室程序时,我们可以使用Socket、Remoting、WCF这些具有双向通信的协议或框架。而现在,我正要实......

内容摘要

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。

publicinterfaceIResponseManager

{

voidWrite(Socket sender, IList < Socket >cliens, IDictionary < string ,object >param);

}

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

publicclassLogonResponseManager : IResponseManager

{

publicvoidWrite(System.Net.Sockets.Socket sender, IList < System.Net.Sockets.Socket >cliens, IDictionary < string ,object >param)

{

Console.WriteLine( " 客户端({0})登陆 " , sender.Handle);

var response=newSocketResponse

{

Method=" Logon " ,

DateTime=DateTime.Now.ToString( " yyyy-MM-dd HH:mm:ss " ),

Result=new{ UserName=param[ " UserName " ].ToString() }

};

JavaScriptSerializer jss=newJavaScriptSerializer();

stringcontext=jss.Serialize(response);

Console.WriteLine( " 登陆发送的数据为:{0} " , context);

sender.Send(Encoding.UTF8.GetBytes(context+" \n " ));

}

}

publicclassSendResponseManager : IResponseManager

{

publicvoidWrite(System.Net.Sockets.Socket sender, IList < System.Net.Sockets.Socket >cliens, IDictionary < string ,object >param)

{

Console.WriteLine( " 客户端({0})发送消息 " , sender.Handle);

var msgList=param[ " Message " ]asIEnumerable < object > ;

if(msgList==null )

{

return ;

}

var response=newSocketResponse

{

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=newJavaScriptSerializer();

stringcontext=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)asIResponseManager;

manager.Write(sender,this .socketClientSesson.Select(s=>s.Key).ToList(),

request.ParamasIDictionary < string ,object > );

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

publicclassSocketHost

{

privateIDictionary < Socket,byte [] >socketClientSesson=newDictionary < Socket,byte [] > ();

publicintPort {get ;set ; }

publicvoidStart()

{

var socketThread=newThread(()=>

{

Socket socket=newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint iep=newIPEndPoint(IPAddress.Any,this .Port);

// 绑定到通道上

socket.Bind(iep);

// 侦听

socket.Listen( 6 );

// 通过异步来处理

socket.BeginAccept( newAsyncCallback(Accept), socket);

});

socketThread.Start();

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

}

privatevoidAccept(IAsyncResult ia)

{

Socket socket=ia.AsyncStateasSocket;

var client=socket.EndAccept(ia);

socket.BeginAccept( newAsyncCallback(Accept), socket);

byte [] buf=newbyte [ 1024 ];

this .socketClientSesson.Add(client, buf);

try

{

client.BeginReceive(buf,0 , buf.Length, SocketFlags.None,newAsyncCallback(Receive), client);

stringsessionId=client.Handle.ToString();

Console.WriteLine( " 客户端({0})已连接 " , sessionId);

}

catch(Exception ex)

{

Console.WriteLine( " 监听请求时出错:\r\n "+ex.ToString());

}

}

privatevoidReceive(IAsyncResult ia)

{

var client=ia.AsyncStateasSocket;

if(client==null||! this .socketClientSesson.ContainsKey(client))

{

return ;

}

intcount=client.EndReceive(ia);

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

if(count>0 )

{

try

{

client.BeginReceive(buf,0 , buf.Length, SocketFlags.None,newAsyncCallback(Receive), client);

stringcontext=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

{

stringsessionId=client.Handle.ToString();

client.Disconnect( true );

this .socketClientSesson.Remove(client);

Console.WriteLine( " 客户端({0})已断开 " , sessionId);

}

catch(Exception ex)

{

Console.WriteLine( " 客户端已断开出错 "+ex.ToString());

}

}

}

privatevoidResponse(Socket sender,stringcontext)

{

SocketRequest request=null ;

JavaScriptSerializer jss=newJavaScriptSerializer();

request=jss.Deserialize(context,typeof (SocketRequest))asSocketRequest;

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)asIResponseManager;

manager.Write(sender,this .socketClientSesson.Select(s=>s.Key).ToList(),

request.ParamasIDictionary < string ,object > );

}

}

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

[Serializable]

publicclassSocketRequest

{

publicstringMethod {get ;set ; }

publicstringDateTime {get ;set ; }

publicobjectParam {get ;set ; }

}

[Serializable]

publicclassSocketResponse

{

publicstringMethod {get ;set ; }

publicstringDateTime {get ;set ; }

publicobjectResult {get ;set ; }

}

四、客户端源代码

1.布局文件

logon.xml:

<? xml version="1.0" encoding="utf-8" ?>

< LinearLayoutxmlns: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" >

< LinearLayoutandroid:orientation ="vertical"

android:layout_width ="fill_parent"android:layout_height ="60dip"

android:background ="@drawable/logon"/>

< LinearLayoutandroid:orientation ="vertical"

android:layout_width ="fill_parent"android:layout_height ="fill_parent"

android:paddingLeft ="10dp"android:paddingRight ="10dp" >

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

< TextViewandroid:id ="@+id/feedback_title"android:textColor ="#FFFFFF"

android:layout_width ="fill_parent"android:layout_height ="wrap_content"

android:text ="用户名:"/>

< EditTextandroid:id ="@+id/edtUserName"android:layout_width ="fill_parent"

android:layout_height ="wrap_content"/>

< Viewandroid:layout_width ="fill_parent"android:layout_height ="2dip"

android:background ="#FF909090"/>

< TextViewandroid:layout_width ="fill_parent"

android:textColor ="#FFFFFF"android:layout_height ="wrap_content"

android:text ="IP地址:"/>

< EditTextandroid:id ="@+id/edtIp"android:layout_width ="fill_parent"

android:layout_height ="wrap_content"android:digits ="1234567890."

android:text ="192.168.1.101" />

< Viewandroid:layout_width ="fill_parent"android:layout_height ="2dip"

android:background ="#FF909090"/>

< TextViewandroid:layout_width ="fill_parent"

android:textColor ="#FFFFFF"android:layout_height ="wrap_content"

android:text ="端口号:"/>

< EditTextandroid:id ="@+id/edtPort"android:layout_width ="fill_parent"

android:layout_height ="wrap_content"android:inputType ="number"

android:numeric ="integer"android:text ="1234" />

< LinearLayoutandroid:orientation ="horizontal"

android:layout_width ="fill_parent"android:layout_height ="wrap_content"

android:layout_marginTop ="10dp" >

</ LinearLayout >

< RelativeLayoutandroid:layout_width ="fill_parent"

android:layout_height ="fill_parent" >

< Viewandroid: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"/>

< Buttonandroid: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" ?>

< LinearLayoutxmlns: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" >

< ListViewandroid:layout_width ="fill_parent"

android:layout_height ="wrap_content"android:id ="@+id/ltvMessage" >

</ ListView >

< RelativeLayoutandroid:layout_width ="fill_parent"

android:layout_height ="wrap_content" >

< EditTextandroid: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"/>

< Buttonandroid: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" ?>

< LinearLayoutxmlns: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" >

< TextViewandroid:layout_height ="wrap_content"

android:layout_width ="fill_parent"android:id ="@+id/itmMessage"

android:textSize ="20dip" >

</ TextView >

< LinearLayoutandroid:layout_width ="fill_parent"

android:orientation ="horizontal"android:layout_height ="20dip" >

< TextViewandroid:layout_height ="fill_parent"

android:layout_width ="100dip"android:id ="@+id/itmUserName">

</ TextView >

< TextViewandroid:layout_height ="fill_parent"

android:layout_width ="200dip"android:id ="@+id/itmTime">

</ TextView >

</ LinearLayout >

</ LinearLayout >

SocketClient:

packageld.socket;

importjava.io.BufferedReader;

importjava.io.BufferedWriter;

importjava.io.IOException;

importjava.io.InputStreamReader;

importjava.io.OutputStreamWriter;

importjava.net.Socket;

importjava.net.UnknownHostException;

importjava.text.SimpleDateFormat;

importjava.util.Date;

importjava.util.HashMap;

importjava.util.Map;

importorg.json.JSONArray;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.os.Handler;

importandroid.os.Message;

importandroid.util.Log;

publicclassSocketClient {

privatestaticSocket client;

privatestaticSocketClient instance=null ;

publicstaticSocketClient getInstance() {

if(instance==null ) {

synchronized(ChartInfo. class ) {

if(instance==null ) {

try{

ChartInfo chartInfo=ChartInfo.getInstance();

client=newSocket(chartInfo.getIp(), chartInfo

.getPort());

instance=newSocketClient();

}catch(UnknownHostException e) {

//TODO Auto-generated catch block

}catch(IOException e) {

//TODO Auto-generated catch block

}

}

}

}

returninstance;

}

privateSocketClient() {

this .initMap();

this .startThread();

}

privatevoidinitMap() {

this .handlerMap=newHashMap < String, Handler > ();

}

publicvoidclose() {

try{

client.close();

}catch(IOException e) {

//TODO Auto-generated catch block

// e.printStackTrace();

}

instance=null ;

}

privatevoidstartThread() {

Thread thread=newThread() {

@Override

publicvoidrun() {

while( true ) {

if(client==null||! client.isConnected()) {

continue ;

}

BufferedReader reader;

try{

reader=newBufferedReader( newInputStreamReader(

client.getInputStream()));

String line=reader.readLine();

Log.d( " initSocket " ," line: "+line);

if(line.equals( "" )) {

continue ;

}

JSONObject json=newJSONObject(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=newMessage();

msg.obj=obj;

handler.sendMessage(msg);

}catch(IOException e) {

}catch(JSONException e) {

}

}

}

};

thread.start();

}

privateMap < String, Handler >handlerMap;

publicvoidputHandler(String methodnName, Handler handler) {

this .removeHandler(methodnName);

this .handlerMap.put(methodnName, handler);

}

publicvoidremoveHandler(String methodnName) {

if( this .handlerMap.containsKey(methodnName)) {

this .handlerMap.remove(methodnName);

}

}

publicvoidlogon(String userName) {

Log.d( " initSocket " ," logon " );

try{

OutputStreamWriter osw=newOutputStreamWriter(client

.getOutputStream());

BufferedWriter writer=newBufferedWriter(osw);

JSONObject param=newJSONObject();

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();

}

}

publicvoidsendMessage(String message) {

Log.d( " initSocket " ," Send " );

try{

OutputStreamWriter osw=newOutputStreamWriter(client

.getOutputStream());

BufferedWriter writer=newBufferedWriter(osw);

JSONArray array=newJSONArray();

for(String item : message.split( " \n " )) {

array.put(item);

}

JSONObject param=newJSONObject();

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();

}

}

privateJSONObject getJSONData(String methodName, JSONObject param) {

JSONObject json=newJSONObject();

try{

json.put( " Method " , methodName);

SimpleDateFormat format=newSimpleDateFormat(

" yyyy-MM-dd HH:mm:ss " );

json.put( " DateTime " , format.format( newDate()));

json.put( " Param " , param);

returnjson;

}catch(JSONException e) {

returnnull ;

}

}

}

LogonActivity:

packageld.socket;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.app.Activity;

importandroid.app.AlertDialog;

importandroid.content.ComponentName;

importandroid.content.DialogInterface;

importandroid.content.Intent;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Message;

importandroid.util.Log;

importandroid.view.KeyEvent;

importandroid.view.View;

importandroid.view.View.OnClickListener;

importandroid.widget.Button;

importandroid.widget.EditText;

publicclassLogonActivityextendsActivity {

privateEditText edtUserName;

privateEditText edtIp;

privateEditText edtPort;

privateButton btnLogon;

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

//TODO Auto-generated method stub

super .onCreate(savedInstanceState);

setContentView(R.layout.logon);

this .initViews();

}

privatevoidinitViews() {

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( newOnClickListener() {

@Override

publicvoidonClick(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 ;

}

intport=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 " ,newHandler() {

@Override

publicvoidhandleMessage(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=newIntent();

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());

}

});

}

privatevoidsetWireless() {

Intent mIntent=newIntent( " / " );

ComponentName comp=newComponentName( " com.android.settings " ,

" com.android.settings.WirelessSettings " );

mIntent.setComponent(comp);

mIntent.setAction( " android.intent.action.VIEW " );

startActivityForResult(mIntent,0 );

}

privatevoidshowDialog(String mess) {

newAlertDialog.Builder( this ).setTitle( " 信息 " ).setMessage(mess)

.setNegativeButton( " 确定 " ,newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialog,intwhich) {

}

}).show();

}

@Override

publicbooleanonKeyDown( intkeyCode, KeyEvent event) {

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

AlertDialog alertDialog=newAlertDialog.Builder(

LogonActivity. this ).setTitle( " 退出程序 " ).setMessage( " 是否退出程序 " )

.setPositiveButton( " 确定 " ,

newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialog,

intwhich) {

LogonActivity. this .finish();

}

}).setNegativeButton( " 取消 " ,

newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialog,intwhich) {

return ;

}

}).create();//创建对话框

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

returnfalse ;

}

returnfalse ;

}

@Override

protectedvoidonDestroy() {

//TODO Auto-generated method stub

super .onDestroy();

SocketClient proxy=SocketClient.getInstance();

if(proxy!=null ) {

proxy.close();

}

}

}

MainActivity:

packageld.socket;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.app.Activity;

importandroid.app.AlertDialog;

importandroid.content.DialogInterface;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Message;

importandroid.util.Log;

importandroid.view.KeyEvent;

importandroid.view.View;

importandroid.view.WindowManager;

importandroid.view.View.OnClickListener;

importandroid.widget.Button;

importandroid.widget.EditText;

importandroid.widget.ListView;

publicclassMainActivityextendsActivity {

privateEditText edtMessage;

privateButton btnSend;

privateListView ltvMessage;

privateMessageAdapter adapter;

/**Called when the activity is first created.*/

@Override

publicvoidonCreate(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=newMessageAdapter( this );

Log.d( " initSocket " ," adapter is ok " );

this .findThisViews();

this .initHandler();

this .serOnClick();

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

}

privatevoidfindThisViews() {

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

}

privatevoidinitHandler() {

Handler handler=newHandler() {

@Override

publicvoidhandleMessage(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=newStringBuilder();

intlength=json.getJSONArray( " Message " ).length();

for( inti=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=newMessageRecord();

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

}

privatevoidserOnClick() {

this .btnSend.setOnClickListener( newOnClickListener() {

@Override

publicvoidonClick(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

publicbooleanonKeyDown( intkeyCode, KeyEvent event) {

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

AlertDialog alertDialog=newAlertDialog.Builder(

MainActivity. this ).setTitle( " 询问 " ).setMessage( " 是否注销登录? " )

.setPositiveButton( " 确定 " ,

newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialog,

intwhich) {

MainActivity. this .finish();

}

}).setNegativeButton( " 取消 " ,

newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialog,intwhich) {

return ;

}

}).create();//创建对话框

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

returnfalse ;

}

returnfalse ;

}

}

五、运行效果

代码下载

赞助本站

人工智能实验室

相关热词: C# Socket服务器 聊天室 Demo

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港