参考文章地址:http://www.cocoachina.com/android/20171016/20806.html
前端布局如下:


Activity中的全部代码,其中使用了butterknife实现View中控件的实例化。

package com.example.a260219.myapplication;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.text.TextUtils;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import java.net.DatagramPacket;import butterknife.ButterKnife;import butterknife.InjectView;import butterknife.OnClick;import utils.UDPSocket;public class AndroidUdpNewAcitivity extends AppCompatActivity {    @InjectView(R.id.tv_receive_ip)    EditText tvReceiveIp;    @InjectView(R.id.tv_receive_port)    TextView tvReceivePort;    @InjectView(R.id.btn_start)    Button btnStart;    @InjectView(R.id.tv_service_msg)    EditText tvServiceMsg;    @InjectView(R.id.btn_send)    Button btnSend;    @InjectView(R.id.btn_reset)    Button btnReset;    @InjectView(R.id.tv_received_ip)    TextView tvReceivedIp;    @InjectView(R.id.tv_receive_msg)    TextView tvReceiveMsg;    private UDPSocket socket;    private String rip;//接收端ip    private String sip;//服务端ip    private int port;    private String message;    private DatagramPacket receivePacket;    int count = 0;    public Handler mhandler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            receivePacket = (DatagramPacket) msg.obj;            String strReceive = new String(receivePacket.getData(), 0, receivePacket.getLength());            tvReceivedIp.setText(receivePacket.getAddress().getHostAddress());            tvReceivePort.setText(receivePacket.getPort() + "");            tvReceiveMsg.setText(strReceive);        }    };    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_new_udp);        ButterKnife.inject(this);    }    public void myToast(String str) {        Toast.makeText(AndroidUdpNewAcitivity.this, str, Toast.LENGTH_SHORT).show();    }    @OnClick({R.id.btn_start, R.id.btn_send,R.id.btn_reset})    public void onClick(View view) {        switch (view.getId()) {            case R.id.btn_start:                if(TextUtils.isEmpty(tvReceiveIp.getText())||TextUtils.isEmpty(tvReceivePort.getText())){                    myToast("接收端ip或者port不能为空");                    return;                }                rip=tvReceiveIp.getText().toString();                port=Integer.parseInt(tvReceivePort.getText().toString());                if(socket==null){                    socket = new UDPSocket(rip, port, this);                }                //注册回调函数                socket.setUIUpdateListener(new UDPSocket.UIUpdateListener() {                    @Override                    public void upUI(DatagramPacket receivePacket) {                        Message msg = new Message();                        msg.obj = receivePacket;                        mhandler.sendMessage(msg);                    }                });                break;            case R.id.btn_send:                if(TextUtils.isEmpty(tvServiceMsg.getText().toString())){                    myToast("发送消息不能为空");                    return;                }                message=tvServiceMsg.getText().toString();                ++count;//记录点击发送的次数                socket.sendMessage(message+count);                break;            case R.id.btn_reset:                tvReceivedIp.setText("");                tvReceiveMsg.setText("");                break;        }    }}
--------------------------- UDPSocket.java中的代码:
 //接口规范    public interface  UIUpdateListener {        void upUI(DatagramPacket receivePacket);    }    public void setUIUpdateListener(UIUpdateListener listener){            startUDPSocket(listener);    }    public void startUDPSocket(UIUpdateListener listener) {        if (client != null) return;        try {                     client = new DatagramSocket(CLIENT_PORT);            if (receivePacket == null) {                          receivePacket = new DatagramPacket(receiveByte, BUFFER_LENGTH);            }            startSocketThread(listener);        } catch (SocketException e) {            e.printStackTrace();        }    }    /**     * 接收数据     */    private void startSocketThread(final UIUpdateListener listener) {        clientThread = new Thread(new Runnable() {            @Override            public void run() {                Log.d(TAG, "clientThread is running...");                receiveMessage(listener);            }        });        isThreadRunning = true;        clientThread.start();     }    /**     * 处理接受到的消息     */    private void receiveMessage(UIUpdateListener listener) {        while (isThreadRunning) {            try {                if (client != null) {                    client.receive(receivePacket);                }                lastReceiveTime = System.currentTimeMillis();                Log.d(TAG, "receive packet success...");            } catch (IOException e) {                Log.e(TAG, "UDP数据包接收失败!线程停止");                stopUDPSocket();                e.printStackTrace();                return;            }            if (receivePacket == null || receivePacket.getLength() == 0) {                Log.e(TAG, "无法接收UDP数据或者接收到的UDP数据为空");                continue;            }            //解析接收到的 json 信息            // 每次接收完UDP数据后,重置长度。否则可能会导致下次收到数据包被截断。            if (receivePacket != null) {                listener.upUI(receivePacket);                receivePacket.setLength(BUFFER_LENGTH);            }        }    }    public void stopUDPSocket() {        isThreadRunning = false;        receivePacket = null;        if (clientThread != null) {            clientThread.interrupt();        }        if (client != null) {            client.close();            client = null;        }        if (timer != null) {            timer.exit();        }/** * 发送 */public void sendMessage(final String message) {    this.BROADCAST_MSG=message;    mThreadPool.execute(new Runnable() {        @Override        public void run() {            try {                InetAddress targetAddress = InetAddress.getByName(BROADCAST_IP);                DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), targetAddress, CLIENT_PORT);                client.send(packet);                // 数据发送事件                Log.d(TAG, "数据发送成功");            } catch (UnknownHostException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }    });}    }

----------------- 总结: 注意在发送之前,需要先点击开启。 在开启的方法中,红色加粗部分的代码 socket.setUIUpdateListener, 是注册的回调函数(后续解释这个回调函数),在这个函数中执行了接受消息的语句。接受和发送消息,需要使用 DatagramSocket套接字和DatagramPacket数据包组装发送和接收的数据, 因为发送和接受信息会阻塞线程,所以发送和接受的方法需要写在子线程中。 发送端:伪代码 1.首先,创建一个发送的DatagramSocket client = new DatagramSocket(CLIENT_PORT); 2.获取接收端的ip地址 InetAddress local = null; try { // 换成服务器端IP local = InetAddress. getByName (ip); } catch (UnknownHostException e) { e.printStackTrace(); } 3.定义发送信息的字节数组 byte[] messageByte = message.getBytes(); 4.创建DatagramPacket包组装数据,然后发送出去 DatagramPacket p = new DatagramPacket(messageByte, msg_length, local, server_port); try { s.send(p); } catch (IOException e) { e.printStackTrace(); } 接收端: 1.创建一个接收消息的字节数组,并规定数组的长度 byte[] message = new byte[1024]; 2.创建接收的DatagramSocket client = new DatagramSocket(CLIENT_PORT); 3.创建接收数据的DatagramPacket receivePacket = new DatagramPacket(receiveByte, BUFFER_LENGTH); client.receive(receivePacket);
补充:说说回调函数。 参考地址: https://blog.csdn.net/a78270528/article/details/46918601 在UDPSocket类中接收到数据以后,需要把接收的数据显示在界面上,使用的回调函数。 什么是回调函数, 简单来说:回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机。就好比这个项目中,回调函数是预留给Activity调用的,当接收到信息的时候进行回调,接收到信息进行UI界面更新的过程就叫”回调“。 如下图:




1.在UDPSocket类中定义一个接口(规范) 2.在Activity中注册接口,提前告诉系统这里有UI的方法等待调用,该方法具体实现更新UI。 3.在UDPSocket类中定义方法开启接受信息的方法,收到消息后调用更新UI的接口,告诉系统要调用注册的监听里的方法了。

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. Android(安卓)Audio延迟(latency)
  4. android 发送短信的两种方式
  5. Android(安卓)Intent 常见用法总结
  6. android中的广播接收器
  7. android 单例
  8. android 单例
  9. 1.5 Android(安卓)入门实例 后台循环发短信

随机推荐

  1. mysql创建数据库,添加用户,用户授权实操
  2. mysql-5.7.28 在Linux下的安装教程图解
  3. mysql 8.0.18 安装配置方法图文教程
  4. MySQL数据库中null的知识点总结
  5. MySQL中sleep函数的特殊现象示例详解
  6. Mysql 8.0.18 hash join测试(推荐)
  7. MySQL 8.0 新特性之哈希连接(Hash Join)
  8. mysql快速获得库中无主键的表实例代码
  9. mysql实现设置定时任务的方法分析
  10. MySQL如何为字段添加默认时间浅析