Android 4.0 Socket调试工具制作过程及源码发布

首先是还是界面设计

分别是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

本文链接:Android 4.0 Socket调试工具制作过程及源码发布

转载声明:BeiTown原创,转载请注明来源:BeiTown's Coder 编码之源,谢谢


Tags: , , ,

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>