Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题

一、Android:Socket客户端开发

创建一个工程

我们要做的是按下按键之后,去往服务器

(服务器)

或者我们自己写的服务器

,给他发送一些预定好的东西

      

然后打开操作界面

 然后修改一下

你要发送消息,需要

android:onClick="sendMessage"

 然后在这里

 修改一下

 如何发送?

CTRL + shirt  +   o   打包

 当按键被按下的时候,我们就做这些

 把这些扔进来

当按键被按下的时候,我们调用        sendMessage 这个东西

调用这个东西我们干啥呢?        连接        Socket client = new Socket("192.168.70.1", 9002);
                                                            OutputStream out= client.getOutputStream();

连接以后我们不要用                Scanner sc = new Scanner(System.in);
                                                            String message = sc.next();

                                                                                   

我们定义一个        String message = "message from Android";

out.write(message.getBytes());        这句话也得改一下

         然后                
                    InputStream in = client.getInputStream();            
                    int len;
                    byte[]data = new byte[128];
                    len = in.read(data);
                    System.out.println("获得服务端返回数据是:"+new String(data,0,len));

        先不做,        获得数据我们先不做,先发一个数据      

现在 的代码

  

 

运行一下

 在夜神模拟器上显示的结果

 点一下发送信息

 然后我们试一下,之前写过的JavaSocket服务端

运行一下

 显示        等待连接

 然后,我们点击一下   夜神模拟器上面的发送消息

 显示已经停止运行

然后logCat最大化

 我们从第三行红字开始看

 再看一下caused by

 

 Network网络访问        onMainThreadException  放在主线程里面的异常

他不让你在主线程里面发送网络访问

        开始我们看第三行,还以为方法找不到吗,实际上它找到了,找到以后进行网络访问的时候崩了,他不让你在主线程里面做网络访问

        那如何解决呢?

        把

        try {
                    Socket client = new Socket("192.168.70.1",9002);
                    OutputStream out= client.getOutputStream();
            
                    String message = "message from Android";
                    out.write(message.getBytes());
        //            
        //            InputStream in = client.getInputStream();            
        //            int len;
        //            byte[]data = new byte[128];
        //            len = in.read(data);
        //            System.out.println("获得服务端返回数据是:"+new String(data,0,len));
            
                } 
                catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

这个东西做成函数分装        

 public void sendMessageHandler()
    {
                                
                        
    }

        然后在这个handler里面,做真正的网络请求,就是try那一部分

            

        按键被按下的时候,我们是不是要启动一个线程呀        new Thread().strat();

在Thread().     加上new runnable

 变成了

在Runnable里面做你真正想要做的事 

 现在的代码:

                        

JavaSocket服务端

                

 安卓Socket客户端:

 

 先运行一下JavaSocket服务端

        

显示

修改一下28行

String message = "message from Android";

 然后在运行一下  安卓Socket客户端:

运行结果

        点击发送消息

        然后显示:有客户端接入
读到消息:message from Android

补充:

,这里最好不要直接从别的地方复制过来代码,要不然容易显示错误

 

二、Android 的Socket客户端优化

那么如果我们有多个按键

然后我们把这四个拖拽一下,在改一下名字

在改一下id

 

然后我们在 MainActivity上面要做一个处理

而不是所有的都是走它            new Thread(new Runnable() {
            
                                                    @Override
                                                    public void run() {
                                                        // TODO Auto-generated method stub
                                                        sendMessageHandler();
                                                    }
                                        }).start();

        

你在这里想干什么事?

 再来个后退

但是有点不妥,不管前进还是后退,他调用的api都是一样的,发送的消息都是一样的

如何办呢?传参呗。

        同时:                变成public void sendMessageHandler(String command)

                                      out.write(message.getBytes());改成        out.write(command.getBytes());

这样函数就分装了

然后  

 String message = "message from Android";这句话就不要了

 

 

同理做出来左右的代码‘

 运行一下

 然后(记得先运行JAVASocket服务端,然后在运行安卓Socket客户端)

 现在的代码,还能进行优化

你每个都在new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    sendMessageHandler("goback");
                }
            }).start();            

 

然后把 

         try {
            Socket client = new Socket("192.168.70.1", 8810);
            OutputStream out= client.getOutputStream();
            out.write(command.getBytes());
                
                    
        } 
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

copy一下,放到run里面

可是现在的command我们拿不到

 解决方法

 下面也可以修改一下

如果想变得整齐的话

思路: 按键被按下的时候,根据不同的id做不同的事情

运行一下

 现在的代码

 

还可以改动一下

你会发现这个方法是单独的

我们可以

然后

 在改动一下,变成静态的变量

 这样你主线程里面的代码就会很舒服

稍加改动一下

记得还要ctrl  + shirt  +o  把包导进来

 

运行一下

三、Android非UI线程修改控件程序崩溃的问题

我们安卓客户端进行网络访问,难免会收到来自服务端的消息,我们上面只是负责发,没有负责收

如果收到消息的话,我们希望让他显示在控件上面

 里面的内容

先把没用的去掉

在这个Activity里面有一个TextView

 

给他来个id         android:id="@+id/textView"

那么xml 和前面如何关联呢?         在.java 里面          public TextView textview;

记得ctrl   + shirt   + o   打包

然后

然后 

 

然后

 做一个强制转换,CTRL   +   1    然后回车

我们下一步拖个按键进来

 

比如这个按键的目标是修改textView        android:text="修改textView为lzp" />

在作一个测试的函数        android:onClick="testFunc"

然后在.Java里面

 记得ctrl  +  shirt   +   o  打包

 然后

 修改一下内容

 运行一下

 点击一下

 那如果我现在想要动态的 刷新

 还需要try  catch 

然后

把    textView.setText("lizhaopeng");   改成             textView.setText("lizhaopeng"+i);

运行一下

发现卡在这里不动了

 那他有没有再跑?

看看能不捕捉到

System.out.println("lizhaopeng"+i);

运行一下,发现一点也没动

 那01234567哪去了?

在UI线程中,不要sleep        ,你真的想sleep你应该创建一个线程sleep            new Thread().start();

 你是不是想把        textView.setText("lizhaopeng"+i);放进去

但是现在这个i不认识

 修改一下

按下按键以后,启动一个线程,这个线程里面去数秒,每隔一秒,修改一次标签

现在的代码

这样主线程就不会阻塞,UI线程就不会被sleep影响,在UI线程之外去操控UI

运行一下

崩调了

我们在UI上显示网络请求,肯定是在线程里面

只是我把网络请求这个事情,我们用for循环做一个简单除暴的信息的变化,然后刷到textView上面去,原理都一样

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值