Android實(shí)現(xiàn)socket通信統(tǒng)一接口的方法
Android實(shí)現(xiàn)socket通信統(tǒng)一接口,統(tǒng)一接口之后可以在不需要大量修改應(yīng)用層代碼的情況下,使用與當(dāng)前功能類似但是底層實(shí)現(xiàn)不同的功能,以實(shí)現(xiàn)的UDP與TCP兩種通信方式的接口為例。
UDP通信與TCP通信的實(shí)現(xiàn)
UDP通信
我們?cè)谑褂肬DP通信方式時(shí),我們會(huì)這樣實(shí)現(xiàn)
//設(shè)置socket
val socket = DatagramSocket()
val serverPort = 9000
val address = InetAddress.getByName("ip地址")
//發(fā)送
val bytes = message.toByteArray(Charsets.UTF_8)
val len = bytes.size
val sendPacket = DatagramPacket(bytes, len, address, serverPort)
socket.send(sendPacket)
//接收
socket.receive(receivePacket)
val data = String(receivePacket.data, Charsets.UTF_8)
//處理接收到的數(shù)據(jù)
//關(guān)閉連接
socket.close()
TCP客戶端通信
我們?cè)谑褂肨CP客戶端通信方式時(shí),我們會(huì)這樣實(shí)現(xiàn)
//設(shè)置socket
val serverPort = 9000
val address = InetAddress.getByName("ip地址")
val socket = Socket(address, serverPort)
val input = socket.getInputStream()
val output = socket.getOutputStream()
//發(fā)送
output.write(message.toByteArray(Charsets.UTF_8))
//接收
val len = input.read(receive)
val data = String(receive, 0, len, Charsets.UTF_8)
//處理接收到的數(shù)據(jù)
//關(guān)閉連接
socket.close()
這樣的話,如果我們需要將應(yīng)用層中的UDP連接轉(zhuǎn)換為T(mén)CP連接,就要大量地修改代碼。
使用統(tǒng)一接口
統(tǒng)一接口之后可以在不需要大量修改應(yīng)用層代碼的情況下,使用與當(dāng)前功能類似但是底層實(shí)現(xiàn)不同的功能。
以之前我們實(shí)現(xiàn)的UDP與TCP兩種通信方式為例,要將其中任意一種轉(zhuǎn)換為另一種時(shí),又或者有新的通信方式需要采用,每次都繁復(fù)地修改應(yīng)用層代碼很明顯不是個(gè)好主意。
我們可以簡(jiǎn)單地分析一下這兩種通信方式,他們都要經(jīng)歷初始化(設(shè)置socket)-> 發(fā)送或者接收 -> 處理數(shù)據(jù) -> 關(guān)閉連接,那我們就可以將這些他們共有的部分抽象出來(lái)給應(yīng)用層使用。
定義接口
新建一個(gè)Communicate.kt文件,實(shí)現(xiàn)Communicate接口
interface Communicate {
/**
* 通信端口
*/
var serverPort: Int
/**
* 通信地址
*/
var address: String
/**
* 輸入編碼
*/
var inCharset: Charset
/**
* 輸出編碼
*/
var outCharset: Charset
/**
* 發(fā)送數(shù)據(jù)
* @param message 數(shù)據(jù)內(nèi)容
*/
fun send(message: String)
/**
* 開(kāi)始接收數(shù)據(jù)
* @param onReceive 處理接收到的數(shù)據(jù)的函數(shù),函數(shù)返回值為是否繼續(xù)接收消息.
* 請(qǐng)不要在函數(shù)中使用stopReceive()函數(shù)停止接收數(shù)據(jù),這不會(huì)起作用。
* @return 是否開(kāi)啟成功
*/
fun startReceive(onReceive: OnReceiveFunc): Boolean
/**
* 停止接收數(shù)據(jù)
*/
fun stopReceive()
/**
* 開(kāi)啟通信,用于TCP建立連接
* @return 是否開(kāi)啟成功
*/
fun open(): Boolean
/**
* 關(guān)閉通信
*/
fun close()
}
上面的代碼塊中還用到了OnReceiveFunc,這用到了kotlin中的類型映射,類似于c語(yǔ)言中的typedef,下面是OnReceiveFunc的實(shí)現(xiàn),他接收一個(gè)字符串作為參數(shù),返回一個(gè)布爾型變量。
typealias OnReceiveFunc = (String) -> Boolean
在具體使用時(shí)利用kotlin的特性,可以直接寫(xiě)OnReceiveFunc方法體。
communicate.startReceive {
binding.textView.text = it
return@startReceive false
}
而在java中的使用方法如下
communicate.startReceive(result -> {
binding.textView.setText(result);
return false;
});
注:這里的communicate是一個(gè)實(shí)現(xiàn)了Communicate接口的通信對(duì)象,而我們并沒(méi)有關(guān)心到底采用了什么通信方式。
這部分中我們可以使用靜態(tài)方法來(lái)讓?xiě)?yīng)用層創(chuàng)建對(duì)象(即選擇想要的連接方式)更加方便。
interface Communicate {
companion object {
@JvmStatic
val TCPClient: Communicate
get() = TCP()
@JvmStatic
val UDP: Communicate
get() = UDP()
}
//其他代碼
}
其中用到了@JvmStatic的注解,這讓java調(diào)用Communicate時(shí)可以少一層companion。
實(shí)現(xiàn)接口
我們?cè)賹?shí)現(xiàn)UDP與TCPClient這兩個(gè)類,他們都實(shí)現(xiàn)了Communicate接口。
我沒(méi)有實(shí)現(xiàn)TCPServer,已經(jīng)實(shí)現(xiàn)的兩種具體實(shí)現(xiàn)可以參考我的gitee倉(cāng)庫(kù)
實(shí)現(xiàn)應(yīng)用層
這樣一來(lái)在應(yīng)用層調(diào)用就可以使用同一種風(fēng)格,比如聲明一個(gè)UDP通信對(duì)象
private val communicate = Communicate.UDP.apply {
address = "ip地址"
serverPort = 9000
inCharset = Charset.forName("gb2312")
outCharset = Charset.forName("gb2312")
open()
}
而聲明一個(gè)TCPClient通信對(duì)象只需要這樣
private val communicate = Communicate.TCPClient.apply {
//與UDP完全一樣
}
而調(diào)用部分就更不用說(shuō)了,完全不需要修改。這樣一來(lái)當(dāng)我們需要修改當(dāng)前通信方式時(shí)只需要將Communicate.UDP改為Communicate.TCPClient,極大地降低了后續(xù)修改的工作量。
總結(jié)
實(shí)現(xiàn)了統(tǒng)一接口之后確實(shí)可以使后續(xù)修改實(shí)現(xiàn)更加方便,程序結(jié)構(gòu)也更加工程化。
到此這篇關(guān)于Android實(shí)現(xiàn)socket通信統(tǒng)一接口 的文章就介紹到這了,更多相關(guān)Android socket通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android TextView不用ScrollViewe也可以滾動(dòng)的方法
這篇文章主要介紹了android TextView不用ScrollViewe也可以滾動(dòng)的方法,很簡(jiǎn)單實(shí)用的代碼,大家參考使用吧2013-11-11
Android利用廣播接收器實(shí)現(xiàn)自動(dòng)填充短信驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了Android利用廣播接收器實(shí)現(xiàn)自動(dòng)填充短信驗(yàn)證碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Kotlin標(biāo)準(zhǔn)庫(kù)函數(shù)使用分析及介紹
Kotlin提供了一個(gè)系統(tǒng)庫(kù),是Java庫(kù)的增強(qiáng)。其中有很多函數(shù)在適配了Java的類型和方法同時(shí)使用Kotlin的語(yǔ)法。其中一些底層的函數(shù) 是使用比較廣泛的2022-09-09
Android自定義控件之可拖動(dòng)控制的圓環(huán)控制條實(shí)例代碼
這篇文章主要介紹了Android自定義控件之可拖動(dòng)控制的圓環(huán)控制條實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
丟失Android系統(tǒng)庫(kù)或者Conversion to Dalvik format failed with error
這篇文章主要介紹了丟失Android系統(tǒng)庫(kù)或者Conversion to Dalvik format failed with error 1錯(cuò)誤的解決方法,分析了Android系統(tǒng)庫(kù)丟失及版本問(wèn)題的處理技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12
Kotlin開(kāi)發(fā)筆記之委托屬性與區(qū)間(譯)
最近在學(xué)習(xí)kotlin,發(fā)現(xiàn)了一些比較重要的知識(shí)點(diǎn),所以下面這篇文章主要給大家介紹了關(guān)于Kotlin開(kāi)發(fā)筆記之委托屬性與區(qū)間的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-12-12

