UDP是一种不靠谱的协议,在大量传输包得情况下容易出现丢包和顺序错乱的情况,在实际开发中使用较少。但因为其快速的简单便捷的使用方式,在传递简洁信息上有着独一无二的优势。
在Android上使用UDP接收信息,使用服务可保持信息的持续接收,因为涉及的联网,需要进行线程操作。
服务中的信息传递到Activity有多种方式:
官方提供Bind的方式可以将服务和Activity绑定来传递消息,但这种做法限制了多个Activity的操作使用,显得不灵活。
当然也可以使用Android的存储机制来完成服务到Activity得操作,好处是存储和查询是分开操作,在开发中只要定义好相同的存储标签就能很好的互通,缺点是增加了程序的运行负载。
最后一种就是在服务中将消息传递给广播,而广播中可以操作界面信息,这样就也实现了数据的传递。缺点也十分的明显,就是界面层和逻辑层交接会比较复杂一点。
以上三种方式是我自己归纳,并不一定完全准确,而且在实际开发中如何使用是根据开发实际情况来灵活变通。
下面就简单介绍一下服务接收UDP消息通过广播显示在界面的操作。
首先,我们需要注册一个服务,并开启服务,配置文件的写法就不贴上了。
Intent intent=new Intent();
intent.setClass(MainActivity.this, MyService.class);
startService(intent);
然后就是在MyService中得操作
public int onStartCommand(Intent intent, int flags, int startId) {
new SocketServer().start();
System.out.println("---start"+"--"+flags+"--"+startId);
return super.onStartCommand(intent, flags, startId);
}
//开启子线程接收UDP协议传输的消息并通过广播发送出去
class SocketServer extends Thread{
@Override
public void run() {
try {
DatagramSocket socket=new DatagramSocket(4567);
byte data[]=new byte[1024];
DatagramPacket packet=new DatagramPacket(data,data.length);
while (true){
socket.receive(packet);
String rs=new String(packet.getData(),packet.getOffset(),packet.getLength());
System.out.println("--" + rs);
if (rs!=null){
//发送广播
Intent intent=new Intent();
intent.putExtra("count", rs); intent.setAction("com.ljq.activity.CountService");
sendBroadcast(intent);
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
super.run();
}
}
在服务中发送的广播是在启动服务前就动态注册的广播,这样就可以在广播中接收传递的消息并进行界面操作。注意,因为是动态注册的广播,所以在界面销毁时广播也会跟着销毁。(静态注册广播会在后面实验后写出用法)
首先是在一开始动态注册的广播:
MyReceiver receiver=new MyReceiver();
IntentFilter filter=new IntentFilter(); filter.addAction("com.ljq.activity.CountService"); MainActivity.this.registerReceiver(receiver, filter);
最后就是在广播中操作界面:
public class MyReceiver extends BroadcastReceiver {
private TextView show;
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Activity activity= (Activity) context;
show= (TextView) activity.findViewById(R.id.txt);
Bundle bundle=intent.getExtras();
String count=bundle.getString("count");
show.setText(count);
Toast.makeText(context,"---",Toast.LENGTH_SHORT).show();
System.out.println("启动了广播!");
}
}