首先是还是界面设计
分别是IP输入、Port输入、连接按钮、接受信息文本框、输入框、发送按钮。
界面设计好之后,为对应控件添加相应功能。
以下是几个相应的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /** * 初始化 */ void init(){ //绑定控件对象 _sendBtn = (Button)findViewById(R.id.sendBtn); _connectBtn = (Button)findViewById(R.id.connectBtn); _ipText = (EditText)findViewById(R.id.ip_editText); _porText = (EditText) findViewById(R.id.port_editText); _rxTextView = (TextView) findViewById(R.id.rx_textView); _txText = (EditText) findViewById(R.id.tx_EditText); _textScrollView = (ScrollView) findViewById(R.id.scrollView); //将按钮添加进监听事件 _sendBtn.setOnClickListener(this); _connectBtn.setOnClickListener(this); } /** * 文本框显示 */ public void printf(String str){ rxTextString += str + "\n"; runOnUiThread(new Runnable() { public void run() { // TODO Auto-generated method stub _rxTextView.setText(rxTextString); _textScrollView.scrollTo(0, _textScrollView.getHeight());//滚动至最后一行 } }); } |
这里要注意,在主线线程之外的线程中直接更新页面显示常会报错。抛出异常:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
解决方法如上文代码中,使用android控件自带的runOnUiThread方法,将更新事件传入主线程排队处理即可。
按钮监听部分的代码,程序会监听之前加入click监听器的控件对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.connectBtn: if(_connectBtn.getText().equals("Connect")){ printf("正在连接..."); connect();//建立连接 rxListenerThread = new TCPListenerThread(inputStream,this);//建立监听线程 rxListenerThread.start(); }else{ //断开连接 onDestroy(); } break; case R.id.sendBtn: sendMessage(_txText.getText().toString());//发送消息 break; default: break; } } |
网络连接的部分参考之前的这篇Android Socket TCP客户端简单实例
这里要注意一下断开连接时的关闭顺序问题,如果在调用socket.close()方法后,还继续对socket.outputStream 或 inputStream进行读写,则会抛出socket closed异常。所以在关闭socket前一定要先关闭客户端的消息监听线程,停止对socket相关流的读写。具体参见源码。
整个程序已经针对Android 4.0以后的版本进行了兼容,4.0版本以后不可在主线程中进行网络连接,因此由原有的在主线程中调用socket连接,改成了在子线程中调用,关于线程间的通信问题参见Android 主线程、子线程间的通信问题
本Demo基本按照之前的两篇博客的知识要点进行了一个简单的举一反三及整合,这里就不再对整个流程说明了,大家具体参考源码。
最后发一个程序在Android手机上的截图:
整个工程打包下载:TcpTest
欢迎大家提出Bug及修改意见。
本篇到此,谢谢关注。
BeiTown
2013.04.15