1. 程式人生 > >Android開發OKSocket第三方庫的使用

Android開發OKSocket第三方庫的使用

最近看GitHub發現有一個不錯的第三方庫oksocket,封裝的很好,自帶連線響應和心跳包等,確實很不錯
地址:https://github.com/xuuhaoo/OkSocket 大家有興趣可以去看看,話不多說,直接上程式碼,一些基礎的設定大家可以按官方的來,配置完後就開始開心擼程式碼了
1、首先宣告一個activity和service,activity負責一些連線的控制(也就是按鈕)加資料讀寫等。
service負責與伺服器的連線,和資料處理,activity用aidl進行通訊
activity程式碼

class MainActivity : AppCompatActivity(),View.OnClickListener{
    //由AIDL檔案生成的Java類
    private var data: SocketAidlInterface? = null
    private var TAG="MainActivity"
    //標誌當前與服務端連線狀況的布林值,false為未連線,true為連線中
    private var mBound=false
    override fun onClick(v: View?) {
        if (!mBound) {
            attemptToBindService()
            Toast.makeText(this, "當前與服務端處於未連線狀態,正在嘗試重連,請稍後再試", Toast.LENGTH_SHORT).show()
            return
        }
        if(data==null)
            return
        when(v!!.id){
            R.id.connection->{
                //伺服器連線
                data!!.socketConnetion("192.168.227.1",1000)
            }
            //傳送資料
            R.id.send->{
               data!!.writeData("hello")
            }
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)
        openServer.setOnClickListener(this)
        connection.setOnClickListener(this)
        send.setOnClickListener(this)
    }
    //連線伺服器
    private fun attemptToBindService() {
        val intent = Intent()
        Log.e(TAG, " connected now")
        intent.action = "com.andrem.gute.socketaidlinterface" //在AndroidManifest.xml進行配置隱形啟動action
        intent.`package`= "com.andrem.gute.tourhotel" //你的包名
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE)
    }

    private val mServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            Log.e(TAG, "service connected")
            data = SocketAidlInterface.Stub.asInterface(service)
            mBound = true
            if (data != null) {
                try {
                   val s= data!!.socketConnetion("192.168.227.1",1000)
                    Log.e(TAG,s)
                } catch (e: RemoteException) {
                    e.printStackTrace()
                }

            }
        }
        override fun onServiceDisconnected(name: ComponentName) {
            Log.e(TAG, "service disconnected")
            mBound = false
        }
    }
    override fun onStart() {
        super.onStart()
        attemptToBindService()
    }

    override fun onStop() {
        super.onStop()
        unbindService(mServiceConnection)
    }

}

service程式碼,寫的很簡單主要看ConnectionDataAidl類

class SocketConnectionService : Service() {

    override fun onBind(intent: Intent): IBinder? {
        return ConnectionDataAidl()
    }
}

ConnectionDataAidl.kt程式碼,設定介面卡負責連線響應和資料讀寫,通過aidl與activity進行資料互動

class ConnectionDataAidl : SocketAidlInterface.Stub() {
    private var mInfo: ConnectionInfo? = null
    private var mOkOptions: OkSocketOptions? = null
    private var mManager: IConnectionManager? = null
    private var serverData="null"
    override fun socketConnetion(ip: String?, port: Int): String {

        initManager(ip,port)

        return if (!mManager!!.isConnect) {
            mManager!!.connect()
            "Connecting"
        } else {
            mManager!!.disconnect()
            "DisConnecting"
        }
    }

     private fun initManager(ip: String?, port: Int){
         mInfo = ConnectionInfo(ip, port)
         mOkOptions = OkSocketOptions.Builder()
                 .setReconnectionManager(NoneReconnect())
                 .setWritePackageBytes(1024)
                 .setCallbackInThread(false)
                 .build()
         mManager = OkSocket.open(mInfo).option(mOkOptions)
         mManager!!.registerReceiver(adapter)
     }

    override fun disconnecting() {
        if (mManager == null) {
            return
        }
        mManager!!.disconnect()
    }

    override fun writeData(data: String?) {
        if (mManager == null) {
            return
        }
        if (!mManager!!.isConnect) {
            return
        } else {
            if (TextUtils.isEmpty(data!!.trim())) {
                return
            }
            val msgDataBean=MsgDataBean(data)
           // MsgDataBean msgDataBean = new MsgDataBean(msg);
            mManager!!.send(msgDataBean)
        }
    }

    override fun readResponse(): String {
        return serverData
    }

    private val adapter = object : SocketActionAdapter() {

        override fun onSocketConnectionSuccess(context: Context?, info: ConnectionInfo?, action: String?) {
            mManager!!.send(HandShake())
        }

        override fun onSocketDisconnection(context: Context?, info: ConnectionInfo?, action: String?, e: Exception?) {
            if (e != null) {
                logSend("異常斷開:" + e.message)
            } else {
                logSend("正常斷開")
            }
        }

        override fun onSocketConnectionFailed(context: Context?, info: ConnectionInfo?, action: String?, e: Exception?) {
            logSend("連線失敗")
        }

        override fun onSocketReadResponse(context: Context?, info: ConnectionInfo?, action: String?, data: OriginalData?) {
            super.onSocketReadResponse(context, info, action, data)
            val str = String(data!!.bodyBytes, Charset.forName("utf-8"))
        }

        override fun onSocketWriteResponse(context: Context?, info: ConnectionInfo?, action: String?, data: ISendable?) {
            super.onSocketWriteResponse(context, info, action, data)
            serverData = String(data!!.parse(), Charset.forName("utf-8"))
            logSend(serverData)
        }

        override fun onPulseSend(context: Context?, info: ConnectionInfo?, data: IPulseSendable?) {
            super.onPulseSend(context, info, data)
            serverData = String(data!!.parse(), Charset.forName("utf-8"))
            logSend(serverData)
        }
    }

    private fun logSend(s: String) {
        Log.e("TAG",s)
    }
}

最後是SocketAidlInterface程式碼

interface SocketAidlInterface {
   //寫資料
   void writeData(String data);
   //獲取放回資料
   String readResponse();
   //socket連線
   String socketConnetion(String ip,int port);
   //斷開socket連線
   void disconnecting();
}