[Android通信]基于socket的聊天app(三):传输json数据

之前传输的都是普通的字符串,但是在实际应用中,客户端会传输各种各样的信息,例如账户、密码和聊天内容等等,那么服务器如何根据字符串区分呢?或许你可以用切割字符串的方法,但我觉得这种方法不是很好。而本人之前了解到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;
	}
}


2.ChatActivity是聊天界面,通过send方法发送信息,同时有一个MessageReceiver,继承自BroadcastReceiver,获取SocketService发过来的信息。在这里你可以看到字符串变成了json格式,以及json格式的字符串被解析了。
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


最后别忘了AndroidManifest.xml

<?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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值