以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<stringobject> param);
    }

 

 

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

 

public class LogonResponseManager : IResponseManager
    {
        
public void Write(System.Net.Sockets.Socket sender, IList<System.Net.Sockets.Socket> cliens, IDictionary<stringobject> 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<stringobject> 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<stringobject>);

 

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

 

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

        
public int Port { getset; }

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

 

 

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

 

   [Serializable]
    
public class SocketRequest
    {
        
public string Method { getset; }

        
public string DateTime { getset; }

        
public object Param { getset; }
    }

 

 

    [Serializable]
    
public class SocketResponse
    {
        
public string Method { getset; }

        
public string DateTime { getset; }

        
public object Result { getset; }
    }

 

 四、客户端源代码

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

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

转载于:https://www.cnblogs.com/GoodHelper/archive/2011/07/08/android_socket_chart.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/263380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maven环境快速搭建

2019独角兽企业重金招聘Python工程师标准>>> 最近&#xff0c;开发中要用到maven&#xff0c;所以对maven进行了简单的学习。因为有个maven高手在身边&#xff0c;所以&#xff0c;很快就上手了&#xff0c;我这里算是自我总结吧。关于maven是什么东东&#xff0c;请…

20190718考试70分记

又考试了&#xff0c;这次题明显感觉难多了&#xff0c;骗了不少分&#xff0c;竟然rk13 第一题一看不可做&#xff0c;然后看第二题 第二题一开始也没有思路&#xff0c;然后我就看上了k<1的情况&#xff0c; 显然k0时只要求所有数的gcd即可&#xff0c; k1的话枚举每一个树…

[散记]今天

前几天还下了一场不小的雪&#xff0c;冷的很。昨天出门还穿了厚毛衣和棉外套&#xff0c;起风的时候还觉得凉飕飕的。今天就热的很了&#xff0c;天气预报说最高温度有16度。出门换了薄毛衣和薄外套&#xff0c;走了一段路&#xff0c;竟是闷热的很&#xff0c;索性将外套脱掉…

火狐、IE浏览器实现Extjs的grid表格的复制、粘贴

2019独角兽企业重金招聘Python工程师标准>>> 从后台获取参数&#xff0c;一次填入ext&#xff1a;grid网状表格&#xff0c;发现表格内的数据不能复制粘贴&#xff0c;只能read...&#xff0c;火狐和IE 11都不能复制。 火狐解决方案 局部定义表格复制、粘贴的样式&a…

Form表单的主要Content-Type

在Spa单页面横行的时代&#xff0c;前后端交互基本都是Json交互&#xff08;也有通过FormData的&#xff0c;比如上传文件&#xff09;。而在之前的Jsp&#xff0c;Php前后不分家的时候&#xff0c;前后交互好大一部分都是通过Form表单来完成的。From标签个属性叫 enctype&…

perl子例程

2019独角兽企业重金招聘Python工程师标准>>> sub 子例程名($$)指定两个标量的参数 ($)指定一个数组 按引用调用 符号引用 typeglob 类似于UNIX文件系统中的软链接 星号(*)适用于任意类型的变量&#xff0c;包括标量&#xff0c;数组&#xff0c;散列&#xff0c;文件…

FormView在什么情况下自动生成模板项?

刚才在鼓捣GridView与FormView&#xff0c;记得前一段时间在做时&#xff0c;点击gridview中的一项会在formview中显示详细的数据&#xff0c;而在 formview中只有编写了ItemTemplate等模板才会显示&#xff0c;我清楚的记得上次我并没有手工去编写itemTemplate模板&#xff0c…

Java遍历Map的几种方式

方法一&#xff1a;使用lambda表达式 Map<Integer, Integer> temp new HashMap<>(); temp.put(1,1); temp.put(2,1); temp.put(3,1); temp.forEach((k, v) -> System.out.println(v));其中&#xff0c;k是键&#xff0c;v是值 运行结果&#xff1a; 方法二&…

Java使用数组作为Map的key

先说结论&#xff1a;Map使用数组作为key&#xff0c;存放的是其地址 我们用如下代码进行测试&#xff1a; 我们的本意是 将[‘a’,‘b’,‘c’]的字符数组存放入map且对应的value为1查询map中是否包含key为[‘a’,‘b’,‘c’]的键值对将[‘a’,‘b’,‘c’]的字符数组对应的…

电脑电视兼容成科技行业新课题

随著深受网民喜爱的网络娱乐节目层出不穷&#xff0c;科技行业一个尚未解决的问题被提上日程&#xff1a;发明让用户得以在电视机上随意收看网络节目的产品。眼下&#xff0c;微软(Microsoft Corp.)、苹果电脑(Apple Computer Inc.)和英特尔(Intel Corp.)等多家行业巨头正在紧锣…

LeetCode—49. 字母异位词分组

49. 字母异位词分组 题目描述&#xff1a; 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的字母得到的一个新单词&#xff0c;所有源单词中的字母通常恰好只用一次。 考察重点&#xff1a;转为…

移动web性能优化笔记

移动web性能优化 最近看了一些文章&#xff0c;对移动web性能优化方法&#xff0c;做一个简单笔记 笔记内容主要出自 移动H5前端性能优化指南和移动前端系列——移动页面性能优化 转载于:https://www.cnblogs.com/GongQi/p/4534392.html

mysql04

连接查询 连接方式 1.交叉连接&#xff1a;交叉连接是将两个表不设定任何条件的连接结果。这种方式会产出好多个无效行。所以不用。 2.内连接 语法 select * from tb_name join tb2_name on tb_name.idtb2_name.id(注意 两个id字段的值应该是相等的&#xff09; 3.外连接 左&am…

我想和你一起去这样一个地方

当我从网站看到这则图片,我不禁惊叹有这样一个世外桃源,可以这样漂亮这样水天一色,我是多渴望能够与深爱的人一起去这个地方,享受我们休闲的白天,度过我们浪漫的夜晚,就这样,我也愿意和你每天每夜呆在一起.当我看到这则相片的时候,我心里只想着他,想和他一起去度假,我很喜欢痴住…

LeetCode—50. Pow(x, n)

50. Pow(x, n) 题目描述&#xff1a; 实现 pow(x, n) &#xff0c;即计算 x 的 n 次幂函数&#xff08;即&#xff0c;x^n &#xff09;。 考察重点&#xff1a;倍乘&#xff0c;使用递归&#xff0c;每次addN取2,4,8,16…个数进行累乘&#xff0c;直到addN > n,则用n-ad…

php结合jquery异步上传图片(ajaxSubmit)

2019独角兽企业重金招聘Python工程师标准>>> php结合jquery异步上传图片&#xff08;ajaxSubmit&#xff09;&#xff0c;以下为提交页面代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/T…

LeetCode—287. 寻找重复数

287. 寻找重复数 题目描述&#xff1a; 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有一个重复的整数 &#xff0c;返回这个重复的数 。 你设计的…

LeetCode—51. N 皇后(困难)

51. N 皇后&#xff08;困难&#xff09; 题目描述&#xff1a; n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击&#xff0c;即令其中任意两个皇后都不同列、同行和在一条斜线上。 给你一个整数 n &#xff0c;返回所有不…

unity 角色换装

unity角色换装的关键是更改角色部位上的物体的SkinnedMeshRenderer组件的属性&#xff1a; 更改mesh:mesh决定了部位的物体的外形&#xff0c;是主要的数据。 刷新骨骼&#xff1a;同一个部位下&#xff0c;不同的mesh受到的不同的骨骼的影响不同&#xff0c;因此更换mesh之后&…

Hadoop:pig 安装及入门示例

pig是hadoop的一个子项目&#xff0c;用于简化MapReduce的开发工作&#xff0c;可以用更人性化的脚本方式分析数据。 一、安装 a) 下载 从官网http://pig.apache.org下载最新版本(目前是0.14.0版本)&#xff0c;最新版本可以兼容hadop 0.x /1.x / 2.x版本&#xff0c;直接解压到…