iterator = readKeys.iterator(); while (iterator.hasNext()) {SelectionKey key = (SelectionKey) iterator.next(); iterator.remove(); if (key.isReadable()) {..... } else if (key.isWritable()) {..... } } }
3. 消息处理机制—Message Handler Looper
Message消息 Handler处理发送和接收消息 Looper管理消息,就是一个手柄
在什么情况下使用消息呢?比如一个子线程,在执行过程中要更改主线程UI的一个控件值,这个时候就需要发送一个消息给主线程,而使用消息处理机制也可以不干扰主线程执行其他操作,在主线程中只要Handler感应到有信息过来它会自己接收,然后处理。代码如下: 在主线程:声明一个Handler
Handler mHandler = new Handler() { @Override
public void handleMessage(Message msg) { super.handleMessage(msg);
} }; 在子线程:
public void sendMessage(String message, int what) {
Message msg = mHandler.obtainMessage(what, 1, 1, message); mHandler.sendMessage(msg); }
注意子线程中的Handler必须是主线程声明的Handler,这样子线程发送的消息才能被主线程Handler认识接收。
4.遇到的问题
1)线程问题:Socket编程中,实现服务器与多个客户端的通信要尽量用多线程机制来实现,当服务器监听到一个客户端的连接就开辟一个线程专门负责与客户端的通信,如果客户端因为某个原因断开与服务器的连接就要及时关闭线程;当然如果是服务器断开了,那么就要关闭所有与客户通信的线程。Android开发中,要注意一点,比较耗时的操作最好开辟一个线程单独执行,不然主线程因为执行这个耗时的操作而耽误执行其他操作,这样导致程序效率很差。
2)网络问题:Android开发中,往往遇到服务器与客户端正在通信时候突然网络断了,这个时候就要关闭socket,但是在关闭socket的时候,双方要知道网络断了才能关闭,如果是人为关闭socket,另一方肯定能检测到,但是是网络突然断开,就不能检测到了,解决这样的方法就是,双方连接上后,每隔一段时间发一个保护数据包,这个数据包双方只管发送,接收不进行处理,如果在一段时间内,一方既没有发送正常的数据包也没有发送保护数据包,那就关闭socket,这样就解决了网络断开的问题导致一方没有及时关闭socket的问题。
3)socket关闭问题:在进行socket编程中,遇到异常或者其他需要断开连接的情况时,socket要及时关闭,而在关闭socket之前,要保证线程关闭;举个列子说下,客户端人为断开与服务器的连接,此时服务器就会检测到与这个客户的通道已经关闭而出现异常,此时服务器就要关闭线程和socket。
还有一个特别重要的问题,在Android开发中,如果服务器与客户端通信的时候,如果没有定义一个协议,只是简单的发送一个字符串,那么如果某一方发送一个空值,这个时候另一方就会默认的认为你没有发送数据。解决这个问题的办法就是,要么定义一个规范的协议发送数据,也就是每发送一个数据都有一个头,要么定义一个专门的数据包(如byte类型的 1 )代表一个空值。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------- 获取手机IP地址 第一种:
public int getIpAddress() {
WifiManager wifiManager = (WifiManager) this.context .getSystemService(Context.WIFI_SERVICE); // 判断wifi是否开启
if (!wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(true); }
WifiInfo wifiInfo = wifiManager.getConnectionInfo(); int ipAddress = wifiInfo.getIpAddress(); return ipAddress; }
private String intToIp(int i) {
return (i & 0xFF) + \".\" + ((i >> 8) & 0xFF) + \".\" + ((i >> 16) & 0xFF) + \".\" + (i >> 24 & 0xFF); } 第二种:
public String getInetIpAddress() { try {
for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement();
for (Enumeration ipAddr = intf.getInetAddresses(); ipAddr .hasMoreElements();) {InetAddress inetAddress = ipAddr.nextElement(); return inetAddress.getHostAddress(); } }
} catch (Exception e) { e.printStackTrace(); }
return null; }