android项目中,测试Socket连接时遇到的问题
2016-04-22 14:54
633 查看
在学习完一个项目之余,随意找了本书阅读,看到了对AsyncTask及另外几种实现线程的方式,由于讲的比较新颖,于是就放下书本,开始码代码了。没想到,这一写,还真的就碰到了以前不曾注意的问题。
1.AsyncTask在一个项目中只能同时运行一个。
2.byte[]的实例化伴随着其中的byte的实例化。
由于是在闲暇时间完成的,所以仅仅只是一个简单的测试程序,仅此而已。
在这次测试中是利用Socket进行两台android设备之间的通信,完成了两个项目——一个是模拟服务器,一个是模拟客户端。
第一个项目(服务器)的代码:
该项目就一个类——MainActivity,由于布局比肩简单粗糙,因此省略。
该类中主要就是SendDataThread和ReadDataThread这两个内部类,这两个类都继承自AsyncTask类,项目运行后ReadDataThread就执行,一直等待客户端的连接,之后循环进行数据的读取与UI更新。
第二个项目(客户端)的代码:
该项目与服务器大同小异。在客户端的界面中多了一个IP设置,除此之外,两个项目大致相同。
在IP设置正确的前提下,能实现客户端与服务器端的聊天(姑且称之为聊天吧),测试目的也基本完成。
在上面列举的面临的两个问题,第一个问题是利用线程池解决,即执行时将execute()方法替换为executeOnExecutor()方法。
第二个问题发生在数据获取、保存时,原本思路是申请一个足够大的byte[],这就导致输出数据时会附带一串无意义的乱码,解决方式如代码。
测试时间仓促,仅为实现联通,难免有所遗漏,请留言告知。
1.AsyncTask在一个项目中只能同时运行一个。
2.byte[]的实例化伴随着其中的byte的实例化。
由于是在闲暇时间完成的,所以仅仅只是一个简单的测试程序,仅此而已。
在这次测试中是利用Socket进行两台android设备之间的通信,完成了两个项目——一个是模拟服务器,一个是模拟客户端。
第一个项目(服务器)的代码:
import java.io.BufferedInputStream; import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import android.app.Activity; import android.app.AlertDialog; import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { private TextView text; // 接收到的消息 private EditText edit; // 发送消息的编辑框 private Button send; // 发送按钮 private ServerSocket server; // 服务器 private Socket client; // 连接的客户端 BufferedInputStream bis; // 输入流 PrintStream ps; // 输出流 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.text = (TextView) findViewById(R.id.text); this.edit = (EditText) findViewById(R.id.edit); this.send = (Button) findViewById(R.id.send); // 接收数据的线程启动 AsyncTask<Void, byte[], Void> read = new ReadDataThread(); read.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); // 为发送按钮设置点击事件 this.send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String str = edit.getText().toString(); new SendDataThread().execute(str); } }); } /** * 发送数据线程 * * @author yufeng * */ private class SendDataThread extends AsyncTask<String, String, Void> { @Override protected Void doInBackground(String... params) { if (client != null) { ps.print(params[0]); } else { publishProgress("无客户端连接,请等待。。。"); } return null; } @Override protected void onProgressUpdate(String... values) { new AlertDialog.Builder(MainActivity.this).setTitle("提示") .setMessage(values[0]).setNeutralButton("取消", null) .create().show(); } } /** * 接收数据数据线程 * * @author yufeng * */ private class ReadDataThread extends AsyncTask<Void, byte[], Void> { @Override protected Void doInBackground(Void... params) { try { // 初始化相关参数 server = new ServerSocket(8888); client = server.accept(); System.out.println("客户端连接成功"); bis = new BufferedInputStream(client.getInputStream()); ps = new PrintStream(client.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } int len; byte[] b; while (client != null) { try { len = bis.available(); if (len > 0) { b = new byte[len]; bis.read(b); publishProgress(b); b = null; } } catch (IOException e) { e.printStackTrace(); } SystemClock.sleep(1000); } return null; } @Override protected void onProgressUpdate(byte[]... values) { byte[] by = values[0]; String msg = new String(by); text.setText("消息:" + msg); } } @Override protected void onStop() { super.onStop(); try { if (bis != null) { bis.close(); } if (ps != null) { ps.close(); } } catch (IOException e) { e.printStackTrace(); } } }
该项目就一个类——MainActivity,由于布局比肩简单粗糙,因此省略。
该类中主要就是SendDataThread和ReadDataThread这两个内部类,这两个类都继承自AsyncTask类,项目运行后ReadDataThread就执行,一直等待客户端的连接,之后循环进行数据的读取与UI更新。
第二个项目(客户端)的代码:
import java.io.BufferedInputStream; import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import android.app.Activity; import android.app.AlertDialog; import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { private TextView text; // 接受到的消息 private EditText edit, ip; // 发送的消息编辑框,IP地址编辑框 private Button send, setIp; // 发送消息按钮,设置IP按钮 private Socket client; // 客户端 BufferedInputStream bis; // 输入流 PrintStream ps; // 输出流 private String strIp = null; // IP地址设置 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.text = (TextView) findViewById(R.id.text); this.edit = (EditText) findViewById(R.id.edit); this.send = (Button) findViewById(R.id.send); this.ip = (EditText) findViewById(R.id.ip); this.setIp = (Button) findViewById(R.id.setIp); // 为发送按钮设置点击事件 this.send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String str = edit.getText().toString(); new SendDataThread().execute(str); } }); // 为IP设置按钮设置点击事件 this.setIp.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { strIp = ip.getText().toString().trim(); // 为了避免测试时在IP设置之前操作该按钮,在xml文件中将发送按钮设置为了不可见 send.setVisibility(View.VISIBLE); // 执行消息发送线程 AsyncTask<Void, byte[], Void> read = new ReadDataThread(); read.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } }); } /** * 发送数据 * * @author yufeng * */ private class SendDataThread extends AsyncTask<String, String, Void> { @Override protected Void doInBackground(String... params) { if (client != null && strIp != null) { ps.print(params[0]); } else { publishProgress("尚未成功连接服务器"); } return null; } @Override protected void onProgressUpdate(String... values) { new AlertDialog.Builder(MainActivity.this).setTitle("提示") .setMessage(values[0]).setNeutralButton("取消", null) .create().show(); } } /** * 接收数据 * * @author yufeng * */ private class ReadDataThread extends AsyncTask<Void, byte[], Void> { @Override protected Void doInBackground(Void... params) { try { // 初始化相关参数 if (client == null) { client = new Socket(strIp, 8888); } bis = new BufferedInputStream(client.getInputStream()); ps = new PrintStream(client.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } int len; byte[] b; while (client != null) { try { len = bis.available(); if (len > 0) { b = new byte[len]; bis.read(b); publishProgress(b); b = null; } } catch (IOException e) { e.printStackTrace(); } SystemClock.sleep(1000); } return null; } @Override protected void onProgressUpdate(byte[]... values) { byte[] by = values[0]; String msg = new String(by); text.setText("消息:" + msg); } } @Override protected void onStop() { super.onStop(); try { if (bis != null) { bis.close(); } if (ps != null) { ps.close(); } } catch (IOException e) { e.printStackTrace(); } } }
该项目与服务器大同小异。在客户端的界面中多了一个IP设置,除此之外,两个项目大致相同。
在IP设置正确的前提下,能实现客户端与服务器端的聊天(姑且称之为聊天吧),测试目的也基本完成。
在上面列举的面临的两个问题,第一个问题是利用线程池解决,即执行时将execute()方法替换为executeOnExecutor()方法。
第二个问题发生在数据获取、保存时,原本思路是申请一个足够大的byte[],这就导致输出数据时会附带一串无意义的乱码,解决方式如代码。
测试时间仓促,仅为实现联通,难免有所遗漏,请留言告知。
相关文章推荐
- android学习之SimpleAdapter
- Android组件标识符
- Android ProGuard 基础学习。
- Android ViewAnimation 使用详解
- android基础知识-Vibrator(振动器) 使用
- Java Future Pattern和Android AsyncTask
- Android Property Animation
- android DecimalFormat使用,保留小数点后x位
- Android 二维码扫描框 加四个角及中间横线自动下滑
- android 百度地图定位开发2
- android 百度地图定位开发1
- Android PullToRefresh (ListView GridView 下拉刷新) 使用详解
- Android 4.4 Graphic系统详解(2) VSYNC的生成
- Android之自定义生成彩色二维码
- Android内存管理机制
- Android Vibrator的使用
- Android API,版本对照
- Android程序框架设计思想01
- Android联系人列表,实现ListView的A-Z字母排序和过滤搜索功能,字母条目上顶
- android shape