Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 通過Socket 和服務器通訊

Android 通過Socket 和服務器通訊

編輯:關於Android編程

Android 通過Socket 和服務器通訊,是一種比較常用的通訊方式,時間比較緊,說下大致的思路,希望能幫到使用socket 進行通信的人   (1)開啟一個線程發送消息    SocketOutputThread         消息是放在隊列裡的,當有消息後,進入隊列,線程喚醒,發送消息,並反饋發送是否成功的回調       (2)開啟一個線程接受服務器消息 SocketInputThread          為了防止一直收數據,浪費電池的電,采用NIO的方式讀socket的數據,這個是本文的關鍵       (3)開啟一個線程,做心跳,防止socket連接終斷 , SocketHeartThread           (4)構建 SocketThreadManager對以上三個thread進行管理       (5)構建 TCPClient 發送socket消息        在NIO的方式實現TCP,特別是在接收服務器的數據,不用寫個線程定時去讀了。        本文地址(http://www.cnblogs.com/likwo/p/3641135.html)           DEMO 截圖       主要代碼如下,詳細代碼在附件裡。       SocketOutPutThread 類     復制代碼 package com.example.socketblockdemo;   import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList;   import android.os.Bundle; import android.os.Handler; import android.os.Message;     /**  * 客戶端寫消息線程  *   * @author way  *   */ public class SocketOutputThread extends Thread {     private boolean isStart = true;     private static String tag = "socketOutputThread";     private List<MsgEntity> sendMsgList;          public SocketOutputThread( )     {           sendMsgList = new CopyOnWriteArrayList<MsgEntity>();     }          public void setStart(boolean isStart)     {         this.isStart = isStart;         synchronized (this)         {             notify();         }     }       // 使用socket發送消息     public boolean sendMsg(byte[] msg) throws Exception     {                                   if (msg == null)         {             CLog.e(tag, "sendMsg is null");             return false;         }                  try         {             TCPClient.instance().sendMsg(msg);                      } catch (Exception e)         {             throw (e);         }                  return true;     }          // 使用socket發送消息     public void addMsgToSendList(MsgEntity msg)      {           synchronized (this)         {             this.sendMsgList.add(msg);             notify();         }     }          @Override     public void run()     {         while (isStart)         {             // 鎖發送list             synchronized (sendMsgList)             {                 // 發送消息                 for (MsgEntity msg : sendMsgList)                 {                                          Handler handler = msg.getHandler();                     try                     {                         sendMsg(msg.getBytes());                         sendMsgList.remove(msg);                         // 成功消息,通過hander回傳                         if (handler != null)                         {                             Message message =  new Message();                             message.obj = msg.getBytes();                             message.what =1;                            handler.sendMessage(message);                         //    handler.sendEmptyMessage(1);                         }                                              } catch (Exception e)                     {                         e.printStackTrace();                         CLog.e(tag, e.toString());                         // 錯誤消息,通過hander回傳                         if (handler != null)                         {                             Message message =  new Message();                             message.obj = msg.getBytes();                             message.what = 0;;                             handler.sendMessage(message);                                                  }                     }                 }             }                          synchronized (this)             {                 try                 {                     wait();                                      } catch (InterruptedException e)                 {                     // TODO Auto-generated catch block                     e.printStackTrace();                 }// 發送完消息後,線程進入等待狀態             }         }              } } 復制代碼 SocketInputThread     復制代碼 package com.example.socketblockdemo;   import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.channels.CancelledKeyException; import java.nio.channels.ClosedSelectorException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset;     import android.content.Intent; import android.text.TextUtils;   /**  * 客戶端讀消息線程  *   * @author way  *   */ public class SocketInputThread extends Thread {     private boolean isStart = true;          private static String tag = "socket";          // private MessageListener messageListener;// 消息監聽接口對象          public SocketInputThread()     {     }          public void setStart(boolean isStart)     {         this.isStart = isStart;     }          @Override     public void run()     {         while (isStart)         {             // 手機能聯網,讀socket數據             if (NetManager.instance().isNetworkConnected())             {                                  if (!TCPClient.instance().isConnect())                 {                     CLog.e(tag, "TCPClient connet server is fail read thread sleep second" +Const.SOCKET_SLEEP_SECOND );                                          try                     {                         sleep(Const.SOCKET_SLEEP_SECOND * 1000);                     } catch (InterruptedException e)                     {                         // TODO Auto-generated catch block                         e.printStackTrace();                     }                 }                                  readSocket();                                  // 如果連接服務器失敗,服務器連接失敗,sleep固定的時間,能聯網,就不需要sleep                                  CLog.e("socket","TCPClient.instance().isConnect() " + TCPClient.instance().isConnect() );                                               }         }     }          public void readSocket()     {         Selector selector = TCPClient.instance().getSelector();         if (selector == null)         {             return;         }         try         {             // 如果沒有數據過來,一直柱塞             while (selector.select() > 0)             {                 for (SelectionKey sk : selector.selectedKeys())                 {                     // 如果該SelectionKey對應的Channel中有可讀的數據                     if (sk.isReadable())                     {                         // 使用NIO讀取Channel中的數據                         SocketChannel sc = (SocketChannel) sk.channel();                         ByteBuffer buffer = ByteBuffer.allocate(1024);                         try                         {                             sc.read(buffer);                         } catch (IOException e)                         {                             // TODO Auto-generated catch block                             e.printStackTrace();                             // continue;                         }                         buffer.flip();                         String receivedString = "";                         // 打印收到的數據                         try                         {                             receivedString = Charset.forName("UTF-8")                                     .newDecoder().decode(buffer).toString();                                                          CLog.e(tag, receivedString);                                                            Intent i = new Intent(Const.BC);                                                          i.putExtra("response", receivedString);                                                          MainActivity.s_context.sendBroadcast(i );                                                      } catch (CharacterCodingException e)                         {                             // TODO Auto-generated catch block                             e.printStackTrace();                         }                         buffer.clear();                         buffer = null;                                                  try                         {                             // 為下一次讀取作准備                             sk.interestOps(SelectionKey.OP_READ);                             // 刪除正在處理的SelectionKey                             selector.selectedKeys().remove(sk);                                                      } catch (CancelledKeyException e)                         {                             e.printStackTrace();                         }                                                                   }                 }             }             // selector.close();             // TCPClient.instance().repareRead();                      } catch (IOException e1)         {             // TODO Auto-generated catch block             e1.printStackTrace();         } catch (ClosedSelectorException e2)         {         }     }      } 復制代碼 SocketHeartHread 心態類     復制代碼 package com.example.socketblockdemo;   import java.io.IOException;   import android.text.TextUtils;     class SocketHeartThread extends Thread {     boolean isStop = false;     boolean mIsConnectSocketSuccess = false;     static SocketHeartThread s_instance;          private TCPClient mTcpClient = null;          static final String tag = "SocketHeartThread";          public static synchronized SocketHeartThread instance()     {         if (s_instance == null)         {             s_instance = new SocketHeartThread();         }         return s_instance;     }          public SocketHeartThread()     {        TCPClient.instance();                 // 連接服務器     //    mIsConnectSocketSuccess = connect();       }       public void stopThread()     {         isStop = true;     }          /**      * 連接socket到服務器, 並發送初始化的Socket信息      *       * @return      */               private boolean reConnect()     {         return TCPClient.instance().reConnect();     }            public void run()     {         isStop = false;         while (!isStop)         {                 // 發送一個心跳包看服務器是否正常                 boolean canConnectToServer = TCPClient.instance().canConnectToServer();                                  if(canConnectToServer == false){                     reConnect();                 }                 try                 {                     Thread.sleep(Const.SOCKET_HEART_SECOND * 1000);                                      } catch (InterruptedException e)                 {                     e.printStackTrace();                 }             }     } } 復制代碼     線程管理類   復制代碼 package com.example.socketblockdemo;   import android.os.Handler; import android.text.TextUtils;     public class SocketThreadManager {          private static SocketThreadManager s_SocketManager = null;          private SocketInputThread mInputThread = null;          private SocketOutputThread mOutThread = null;          private SocketHeartThread mHeartThread = null;            // 獲取單例     public static SocketThreadManager sharedInstance()     {         if (s_SocketManager == null)         {             s_SocketManager = new SocketThreadManager();             s_SocketManager.startThreads();         }         return s_SocketManager;     }          // 單例,不允許在外部構建對象     private SocketThreadManager()     {         mHeartThread = new SocketHeartThread();         mInputThread = new SocketInputThread();         mOutThread = new SocketOutputThread();     }          /**      * 啟動線程      */          private void startThreads()     {         mHeartThread.start();         mInputThread.start();         mInputThread.setStart(true);         mOutThread.start();         mInputThread.setStart(true);         // mDnsthread.start();     }          /**      * stop線程      */     public void stopThreads()     {         mHeartThread.stopThread();         mInputThread.setStart(false);         mOutThread.setStart(false);     }          public static void releaseInstance()     {         if (s_SocketManager != null)         {             s_SocketManager.stopThreads();             s_SocketManager = null;         }     }          public void sendMsg(byte [] buffer, Handler handler)     {         MsgEntity entity = new MsgEntity(buffer, handler);         mOutThread.addMsgToSendList(entity);     }      }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved