Android实时绘制效果(一)

简介:

 

 Android实时绘制效果

一、概述
         通过长连接的Socket通信,实时发送绘制信息给各客户端,以实现实时显示效果。
 
二、运行效果
       
 
三、功能代码
1 )通信部分
         长连接的Socket通信,支持多客户端。服务器和客户端都可主动发送消息。消息的话,将Object转成了json字符串了。
         之前用ObjectOutputStream多客户端传送对象时遇到了问题,又搜索了下,参见该网址: http://blog.csdn.net/jsjboss/article/details/752193。也就是要建立了ObjectOutputStream的集合,来传消息了?总之,服务器通过Socket集合每次new个ObjectOutputStream来发消息是不成的!

         ps:不想转json,还是想用ObjectOutputStream发送的,可参照《Java Socket通信》长连接通信内的对象消息样例。

 
1.1)EasyServer.java

 
 
  1. /** 
  2.  * 长连接、1对n主动发消息的服务器 
  3.  *  
  4.  * @author Join 
  5.  */ 
  6. public class EasyServer extends Thread { 
  7.  
  8.     /** 退出命令 */ 
  9.     public static final String EXIT_COMMAND = "end"
  10.  
  11.     /** 服务端口 */ 
  12.     private int port; 
  13.     /** 服务套接字 */ 
  14.     private ServerSocket mServerSocket; 
  15.     /** 线程池 */ 
  16.     private ExecutorService pool; 
  17.     /** 客户端套接字集合 */ 
  18.     private ArrayList<Socket> mClientList; 
  19.     /** 服务器监听接口 */ 
  20.     private OnServerListener listener; 
  21.  
  22.     public EasyServer(int port) { 
  23.         this.port = port; 
  24.         pool = Executors.newCachedThreadPool(); // 缓存线程池 
  25.         mClientList = new ArrayList<Socket>(); 
  26.     } 
  27.  
  28.     @Override 
  29.     public void run() { 
  30.         try { 
  31.             mServerSocket = new ServerSocket(port); // 创建本地特定端口服务器套接字 
  32.             Socket client = null
  33.             while (true) { 
  34.                 client = mServerSocket.accept(); // 接收连接的套接字 
  35.                 mClientList.add(client); // 加入客户端列表 
  36.                 if (null != listener) { 
  37.                     listener.onClientConnected(client.getInetAddress()); 
  38.                 } 
  39.                 pool.execute(new ThreadServer(client)); // 新线程执行任务 
  40.             } 
  41.         } catch (BindException e) { // 端口使用中 
  42.             if (null != listener) { 
  43.                 listener.onBindException(); 
  44.             } 
  45.         } catch (IOException e) { 
  46.             e.printStackTrace(); 
  47.         } 
  48.     } 
  49.  
  50.     /** 各个连接客户端的服务线程 */ 
  51.     private class ThreadServer extends Thread { 
  52.  
  53.         private Socket client; 
  54.  
  55.         public ThreadServer(Socket client) { 
  56.             this.client = client; 
  57.         } 
  58.  
  59.         @Override 
  60.         public void run() { 
  61.             DataInputStream in = null
  62.             try { 
  63.                 in = new DataInputStream(client.getInputStream()); 
  64.                 while (true) { 
  65.                     /* 接收数据消息 */ 
  66.                     String msg = in.readUTF(); 
  67.                     if (EXIT_COMMAND.equals(msg)) { 
  68.                         /* 接收退出命令时,处理退出 */ 
  69.                         DataOutputStream out = new DataOutputStream( 
  70.                                 client.getOutputStream()); 
  71.                         out.writeUTF(EXIT_COMMAND); // 再返回至客户端,使得退出循环 
  72.                         out.flush(); 
  73.                         if (null != listener) { 
  74.                             listener.onExited(client.getInetAddress()); 
  75.                         } 
  76.                         break
  77.                     } else { 
  78.                         /* 否则,处理接收消息*/ 
  79.                         if (null != listener) { 
  80.                             listener.onReceive(client.getInetAddress(), msg); 
  81.                         } 
  82.                     } 
  83.                     /* 回复或转发已接收数据 */ 
  84.                 } 
  85.             } catch (SocketException e) { // Connection reset 
  86.                 if (null != listener) { 
  87.                     listener.onSocketException(client.getInetAddress()); 
  88.                 } 
  89.             } catch (IOException e) { 
  90.                 e.printStackTrace(); 
  91.             } finally { 
  92.                 mClientList.remove(client); // 移除当前客户端 
  93.                 try { 
  94.                     if (null != in) { 
  95.                         in.close(); 
  96.                     } 
  97.                     if (null != client) { 
  98.                         client.close(); 
  99.                     } 
  100.                 } catch (IOException e) { 
  101.                     e.printStackTrace(); 
  102.                 } 
  103.             } 
  104.         } 
  105.  
  106.     } 
  107.  
  108.     /** 向客户端群发信息  */ 
  109.     public void sendMessage(String msg) { 
  110.         int i = 0
  111.         try { 
  112.             DataOutputStream out = null
  113.             for (; i < mClientList.size(); i++) { 
  114.                 out = new DataOutputStream(mClientList.get(i).getOutputStream()); 
  115.                 out.writeUTF(msg); 
  116.                 out.flush(); 
  117.             } 
  118.         } catch (SocketException e) { // Connection reset 
  119.             if (null != listener && mClientList.size() > 0) { 
  120.                 listener.onSocketException(mClientList.get(i).getInetAddress()); 
  121.             } 
  122.             mClientList.remove(i); // 移除出异常的那个客户端 
  123.         } catch (IOException e) { 
  124.             e.printStackTrace(); 
  125.             mClientList.remove(i); // 移除出异常的那个客户端 
  126.         } 
  127.     } 
  128.  
  129.     /** 设置服务器监听接口 */ 
  130.     public void setOnServerListener(OnServerListener listener) { 
  131.         this.listener = listener; 
  132.     } 
  133.  
 
1.2)EasyClient.java

 
 
  1. /** 
  2.  * 接收和发送消息的客户端 
  3.  *  
  4.  * @author Join 
  5.  */ 
  6. public class EasyClient extends Thread { 
  7.     (还报8W字符冗余,受不住了,就这么着吧T^T)...
 
1.3)JsonUtil.java

 
 
  1. public class JsonUtil { 
  2.  
  3.     /** 
  4.      * 解析Object成为json 
  5.      *  
  6.      * @param obj 对象 
  7.      * @return json字符串 
  8.      */ 
  9.     public static String objToJson(Object obj) { 
  10.         JSONStringer arrayJson = new JSONStringer(); // Json构造对象 
  11.         Class<?> clazz = obj.getClass(); // 获取对象运行时类 
  12.         try { 
  13.             arrayJson.array().value(clazz.getName()); // 创建数组,第一位存放类名 
  14.             JSONStringer objJson = new JSONStringer(); // Json构造对象 
  15.             objJson.object(); 
  16.             Field[] fields = clazz.getDeclaredFields(); // 返回类声明的所有字段 
  17.             for (Field field : fields) { 
  18.                 field.setAccessible(true); // 设置变量可访问 
  19.                 objJson.key(field.getName()).value(field.get(obj)); 
  20.             } 
  21.             objJson.endObject(); 
  22.             arrayJson.value(objJson).endArray(); // 第二位存放类对象 
  23.         } catch (IllegalArgumentException e) { 
  24.             e.printStackTrace(); 
  25.         } catch (IllegalAccessException e) { 
  26.             e.printStackTrace(); 
  27.         } catch (JSONException e) { 
  28.             e.printStackTrace(); 
  29.         } 
  30.         return arrayJson.toString(); 
  31.     } 
  32.  
  33.     /** 
  34.      * 解析json成为Object 
  35.      *  
  36.      * @param json json字符串 
  37.      * @return 对象 
  38.      * @warning 由于是使用newInstance()构建实例,自己写构造函数时要显式写明默认构造函数 
  39.      */ 
  40.     public static Object jsonToObj(String json) { 
  41.         Object obj = null
  42.         try { 
  43.             JSONArray jarray = new JSONArray(json); 
  44.             String className = jarray.getString(0); // 获得第一位类名 
  45.             Class<?> clazz = Class.forName(className); // 载入该类 
  46.             obj = clazz.newInstance(); // 构建实例 
  47.  
  48.             JSONObject jobj = new JSONObject(jarray.getString(1)); // 获得第二位类对象 
  49.             @SuppressWarnings("unchecked"
  50.             Iterator<String> it = jobj.keys(); 
  51.             Field field; 
  52.             while (it.hasNext()) { 
  53.                 String key = it.next(); 
  54.                 field = clazz.getDeclaredField(key); 
  55.                 setValue(obj, field, jobj.getString(key)); 
  56.             } 
  57.         } catch (Exception e) { 
  58.             e.printStackTrace(); 
  59.         } 
  60.         return obj; 
  61.     } 
  62.  
  63.     /** 
  64.      * 给字段设值 
  65.      *  
  66.      * @param obj 对象 
  67.      * @param field 字段 
  68.      * @param value 值 
  69.      */ 
  70.     private static void setValue(Object obj, Field field, String value) 
  71.             throws IllegalArgumentException, IllegalAccessException { 
  72.       ...
  73.     } 
  74.  
 
 


     本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/893886,如需转载请自行联系原作者



相关文章
|
Android开发
Android绘制竖直虚线完美解决方案—自定义View
开发中我们经常会遇到绘制虚线的需求,一般我们使用一个drawable文件即可实现,下面我会先列举常规drawable文件的实现方式。
|
Android开发
Android进阶之绘制-自定义View完全掌握(一)
Android进阶之绘制-自定义View完全掌握(一)
113 0
Android进阶之绘制-自定义View完全掌握(一)
|
前端开发 Android开发
Android进阶之绘制-自定义View完全掌握(四)
Android进阶之绘制-自定义View完全掌握(四)
107 0
Android进阶之绘制-自定义View完全掌握(四)
|
编解码 Android开发
Android进阶之绘制-自定义View完全掌握(三)
Android进阶之绘制-自定义View完全掌握(三)
156 0
Android进阶之绘制-自定义View完全掌握(三)
|
XML Android开发 数据格式
Android进阶之绘制-自定义View完全掌握(二)
Android进阶之绘制-自定义View完全掌握(二)
100 0
Android进阶之绘制-自定义View完全掌握(二)
|
Android开发
Android自定义控件 | View绘制原理(画什么?)
从源码的角度分析“绘制(draw)”。View绘制只决定绘制的顺序,具体绘制内容由各个子View自己决定。
191 0
|
算法 Android开发
Android自定义控件 | View绘制原理(画在哪?)
从源码的角度分析“定位(layout)”。 位置都是相对的,比如“我在你的右边”、“你在广场的西边”。为了表明位置,总是需要一个参照物。。。
130 0
|
算法 Android开发
Android自定义控件 | View绘制原理(画多大?)
这一篇将以源码中的几个关键函数为线索分析“测量(measure)”。 如果想直接看结论可以移步到第三篇末尾。 真正的测量工作在onMeasure()中进行。。。
110 0
|
前端开发 Android开发
Android 开发进阶: 自定义 View 1-1 绘制基础
Android 开发进阶: 自定义 View 1-1 绘制基础
123 0
|
存储 前端开发 Linux
Android窗口管理分析(4):Android View绘制内存的分配、传递、使用
Android窗口管理分析(4):Android View绘制内存的分配、传递、使用
356 0