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.  
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章