天天看點

Android實時繪制效果(一)

 <b>Android</b><b>實時繪制效果</b>

<b>一、概述</b>

         通過長連接配接的Socket通信,實時發送繪制資訊給各用戶端,以實作實時顯示效果。

<b>二、運作效果</b>

<b>三、功能代碼</b>

<b>1</b><b>)通信部分</b>

         長連接配接的Socket通信,支援多用戶端。伺服器和用戶端都可主動發送消息。消息的話,将Object轉成了json字元串了。

         ps:不想轉json,還是想用ObjectOutputStream發送的,可參照《Java Socket通信》長連接配接通信内的對象消息樣例。

1.1)EasyServer.java

/** 

 * 長連接配接、1對n主動發消息的伺服器 

 *  

 * @author Join 

 */ 

public class EasyServer extends Thread { 

    /** 退出指令 */ 

    public static final String EXIT_COMMAND = "end"; 

    /** 服務端口 */ 

    private int port; 

    /** 服務套接字 */ 

    private ServerSocket mServerSocket; 

    /** 線程池 */ 

    private ExecutorService pool; 

    /** 用戶端套接字集合 */ 

    private ArrayList&lt;Socket&gt; mClientList; 

    /** 伺服器監聽接口 */ 

    private OnServerListener listener; 

    public EasyServer(int port) { 

        this.port = port; 

        pool = Executors.newCachedThreadPool(); // 緩存線程池 

        mClientList = new ArrayList&lt;Socket&gt;(); 

    } 

    @Override 

    public void run() { 

        try { 

            mServerSocket = new ServerSocket(port); // 建立本地特定端口伺服器套接字 

            Socket client = null; 

            while (true) { 

                client = mServerSocket.accept(); // 接收連接配接的套接字 

                mClientList.add(client); // 加入用戶端清單 

                if (null != listener) { 

                    listener.onClientConnected(client.getInetAddress()); 

                } 

                pool.execute(new ThreadServer(client)); // 新線程執行任務 

            } 

        } catch (BindException e) { // 端口使用中 

            if (null != listener) { 

                listener.onBindException(); 

        } catch (IOException e) { 

            e.printStackTrace(); 

        } 

    /** 各個連接配接用戶端的服務線程 */ 

    private class ThreadServer extends Thread { 

        private Socket client; 

        public ThreadServer(Socket client) { 

            this.client = client; 

        @Override 

        public void run() { 

            DataInputStream in = null; 

            try { 

                in = new DataInputStream(client.getInputStream()); 

                while (true) { 

                    /* 接收資料消息 */ 

                    String msg = in.readUTF(); 

                    if (EXIT_COMMAND.equals(msg)) { 

                        /* 接收退出指令時,處理退出 */ 

                        DataOutputStream out = new DataOutputStream( 

                                client.getOutputStream()); 

                        out.writeUTF(EXIT_COMMAND); // 再傳回至用戶端,使得退出循環 

                        out.flush(); 

                        if (null != listener) { 

                            listener.onExited(client.getInetAddress()); 

                        } 

                        break; 

                    } else { 

                        /* 否則,處理接收消息*/ 

                            listener.onReceive(client.getInetAddress(), msg); 

                    } 

                    /* 回複或轉發已接收資料 */ 

            } catch (SocketException e) { // Connection reset 

                    listener.onSocketException(client.getInetAddress()); 

            } catch (IOException e) { 

                e.printStackTrace(); 

            } finally { 

                mClientList.remove(client); // 移除目前用戶端 

                try { 

                    if (null != in) { 

                        in.close(); 

                    if (null != client) { 

                        client.close(); 

                } catch (IOException e) { 

                    e.printStackTrace(); 

    /** 向用戶端群發資訊  */ 

    public void sendMessage(String msg) { 

        int i = 0; 

            DataOutputStream out = null; 

            for (; i &lt; mClientList.size(); i++) { 

                out = new DataOutputStream(mClientList.get(i).getOutputStream()); 

                out.writeUTF(msg); 

                out.flush(); 

        } catch (SocketException e) { // Connection reset 

            if (null != listener &amp;&amp; mClientList.size() &gt; 0) { 

                listener.onSocketException(mClientList.get(i).getInetAddress()); 

            mClientList.remove(i); // 移除出異常的那個用戶端 

    /** 設定伺服器監聽接口 */ 

    public void setOnServerListener(OnServerListener listener) { 

        this.listener = listener; 

1.2)EasyClient.java

 * 接收和發送消息的用戶端 

public class EasyClient extends Thread { 

    (還報8W字元備援,受不住了,就這麼着吧T^T)...

1.3)JsonUtil.java<b></b>

public class JsonUtil { 

    /** 

     * 解析Object成為json 

     *  

     * @param obj 對象 

     * @return json字元串 

     */ 

    public static String objToJson(Object obj) { 

        JSONStringer arrayJson = new JSONStringer(); // Json構造對象 

        Class&lt;?&gt; clazz = obj.getClass(); // 擷取對象運作時類 

            arrayJson.array().value(clazz.getName()); // 建立數組,第一位存放類名 

            JSONStringer objJson = new JSONStringer(); // Json構造對象 

            objJson.object(); 

            Field[] fields = clazz.getDeclaredFields(); // 傳回類聲明的所有字段 

            for (Field field : fields) { 

                field.setAccessible(true); // 設定變量可通路 

                objJson.key(field.getName()).value(field.get(obj)); 

            objJson.endObject(); 

            arrayJson.value(objJson).endArray(); // 第二位存放類對象 

        } catch (IllegalArgumentException e) { 

        } catch (IllegalAccessException e) { 

        } catch (JSONException e) { 

        return arrayJson.toString(); 

     * 解析json成為Object 

     * @param json json字元串 

     * @return 對象 

     * @warning 由于是使用newInstance()建構執行個體,自己寫構造函數時要顯式寫明預設構造函數 

    public static Object jsonToObj(String json) { 

        Object obj = null; 

            JSONArray jarray = new JSONArray(json); 

            String className = jarray.getString(0); // 獲得第一位類名 

            Class&lt;?&gt; clazz = Class.forName(className); // 載入該類 

            obj = clazz.newInstance(); // 建構執行個體 

            JSONObject jobj = new JSONObject(jarray.getString(1)); // 獲得第二位類對象 

            @SuppressWarnings("unchecked") 

            Iterator&lt;String&gt; it = jobj.keys(); 

            Field field; 

            while (it.hasNext()) { 

                String key = it.next(); 

                field = clazz.getDeclaredField(key); 

                setValue(obj, field, jobj.getString(key)); 

        } catch (Exception e) { 

        return obj; 

     * 給字段設值 

     * @param field 字段 

     * @param value 值 

    private static void setValue(Object obj, Field field, String value) 

            throws IllegalArgumentException, IllegalAccessException { 

      ...

<a target="_blank" href="http://vaero.blog.51cto.com/4350852/893887">Android實時繪制效果(二)(附件工程在該篇内)</a>

     本文轉自winorlose2000 51CTO部落格,原文連結:http://blog.51cto.com/vaero/893886,如需轉載請自行聯系原作者