之前传输的都是普通的字符串,但是在实际应用中,客户端会传输各种各样的信息,例如账户、密码和聊天内容等等,那么服务器如何根据字符串区分呢?或许你可以用切割字符串的方法,但我觉得这种方法不是很好。而本人之前了解到json是一个强大的东西,所以打算用json来搞。
效果图(好像跟之前的没什么区别。。。):
主要就两个类:
1.SocketService是一个服务,通过调用send方法向服务器端发送数据,同时SocketService在初始化时开启一个线程,负责接受从服务器发过来的消息,并广播。
package com.example.mysocketclient;
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 android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class SocketService extends Service {
private static Socket socket;
private static BufferedWriter bWriter;//输出流,发送、写入信息
private static BufferedReader bReader;//输入流,接受、读取信息
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(SocketService.this, "connect success", Toast.LENGTH_LONG).show();
new Thread(new Runnable() {
public void run() {
try {
socket = new Socket("172.25.225.24",1989);
bWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null
String s;
while ((s = bReader.readLine()) != null) {
Intent intent = new Intent();
intent.putExtra("jsonString", s);
intent.setAction("SocketClient");
sendBroadcast(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public static void Send(String jsonString)
{
jsonString += "\n";
try {
bWriter.write(jsonString);
bWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
package com.example.mysocketclient;
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.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ChatActivity extends Activity {
private EditText editText;
private Button sendButton;
private Button backButton;
private ListView listView;
private ChatMsgListViewAdapter adapter;
private List<ChatMsgEntity> list;
private MessageReceiver messageReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText = (EditText)findViewById(R.id.editText);
sendButton = (Button)findViewById(R.id.btn_send);
backButton = (Button)findViewById(R.id.btn_back);
listView = (ListView)findViewById(R.id.listview);
sendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
send();
}
});
list = new ArrayList<ChatMsgEntity>();
adapter = new ChatMsgListViewAdapter(this, list);
listView.setAdapter(adapter);
initMessageReceiver();
}
private void send()
{
String content = editText.getText().toString();
if(content.length() > 0) {
ChatMsgEntity entity = new ChatMsgEntity();
entity.setName("me");
entity.setDate(getDate());
entity.setMessage(content);
entity.setMsgType(true);
list.add(entity);
adapter.notifyDataSetChanged();//通知ListView,数据已发生改变
listView.setSelection(listView.getCount() - 1);//发送一条消息时,ListView显示选择最后一项
editText.setText("");
try {
JSONObject root = new JSONObject();
root.put("content", content);
SocketService.Send(root.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private String getDate()
{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return format.format(new Date(0));
}
private void initMessageReceiver()
{
messageReceiver = new MessageReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("SocketClient");
registerReceiver(messageReceiver,filter);
Intent i = new Intent(ChatActivity.this,SocketService.class);
startService(i);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(messageReceiver);
stopService(new Intent(this,SocketService.class));
}
public class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String content = intent.getStringExtra("jsonString");
try {
JSONObject root = new JSONObject(content);
if(content.length() > 0) {
ChatMsgEntity entity = new ChatMsgEntity();
entity.setName("other");
entity.setDate(getDate());
entity.setMessage(root.getString("content"));
entity.setMsgType(false);
list.add(entity);
adapter.notifyDataSetChanged();//通知ListView,数据已发生改变
listView.setSelection(listView.getCount() - 1);//发送一条消息时,ListView显示选择最后一项
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
在服务器那要解析json,要用到jar文件,这里我用的是org.json这个包:
http://pan.baidu.com/s/1eQubJwe
如何导入:
http://jingyan.baidu.com/article/72ee561aba4e2ce16138df00.html
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mysocketclient"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"/>
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".ChatActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".SocketService"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>