@H_403_0@通信方式主要有HTTP和Socket。
- HTTP通信:即使用HTTP协议进行通信,工作原理是客户端向服务器端发送一条HTTP请求,服务器收到之后先解析客户端的请求,之后会返回数据给客户端,然后客户端再对这些数据进行解析和处理。HTTP连接采取的是“请求—响应”方式,即在请求时建立连接通道,当客户端像服务器端发送请求时,服务器端才能向客户端发送数据。
- Socket通信:Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。通过建立socket连接,可为通信双方的数据传输传提供通道。Socket的主要特点有数据丢失率低,使用简单且易于移植。Socket类似于peer to peer的连接,一方可随时向另一方喊话。
- 数据流
- XML
- Protocol Buffers
- JSON
- ⾯面向资源(URI),具有解释性;
- 行为(GET / POST / PUT / PATCH / DELETE)与资源(URI)分离,更更加轻量量;
- 数据描述简单,使⽤用JSON、XML、Protocol Buffers即可全覆盖,主要使用JSON;
- GET :读取(Read)
- POST :新建(Create)
- PUT :更新(Update),通常是全部更更新
- PATCH :更新(Update),通常是部分更更新
- DELETE :删除(Delete)
- Number:整数或浮点数
- String:字符串
- Boolean:true 或 false
- Array:数组包含在方括号[]中
- Object:对象包含在大括号{}中
- Null:空类型
{ "code": 1000,"message": "成功" }@H_403_0@数据解析工具类:
abstract class BaseStringCallback: BaseCallback() { override fun onSuccess(data: String) { val responseData = JSONObject(data) val code = responseData.getInt("code") val message = responseData.getString("message") if (code == 1000) { success(message) } else { //其他状态 } } abstract fun success(msg: String) }@H_403_0@调用时(伪代码):
logoutApi.execute(object : BaseStringCallback() { override fun success(msg: String) { //处理数据 })@H_403_0@5.2 Object数据类型 @H_403_0@识别标示为:{} @H_403_0@使用场景:如获取当前用户信息,返回owner实体类,这个类我们可以直接用Gson的工具类转换为owner实体类。
{ "code": 1000,"message": "成功","resp": { "owner": { "id": 58180,"name": "张三","idCert": "","certType": 1,"modifier": "jun5753","updateTime": 1567127656436 },} }@H_403_0@Json数据转换为实体类工具类:
abstract class BaSEObjectCallback<T>(private val clazz: Class<T>) : BaseCallback() { override fun onSuccess(data: String) { val responseData = JSONObject(data) val code = responseData.getInt("code") val message = responseData.getString("message") if (code == 1000) { val disposable = Observable.just(responseData) .map { it.getJSONObject("resp").toString() } .map { JsonUtil.parSEObject(it,clazz)!! } .applyScheduler() .subscribe( { success(it) },{ //异常时处理 }) } else { //其他状态时处理 } } abstract fun success(data: T) }@H_403_0@调用时(伪代码):
LaunchApi.getOwerInfo.execute(object : BaSEObjectCallback<OwnerEntity>(OwnerEntity::class.java) { override fun success(data: OwnerEntity) { //处理数据 })@H_403_0@5.3. Array数据类型 @H_403_0@识别标示为:[] @H_403_0@使用场景:如获取联系人列表,返回的数据是contact列表,如 ArrayList<contact >。
{ "code": 1000,"resp": { "contact": [ { "id": 5819,"name": "来啦","phone": "","address": "哈哈哈","province": "湖南省","city": "长沙市","area": "芙蓉区","isOwner": 0,"updateTime": 1566461377761 },{ "id": 5835,"name": "小六","phone": "13908258239","address": "天安门","province": "北京市","city": "北京市","area": "东城区","updateTime": 1567150580553 } ] } }@H_403_0@Json数据转换为实体类列表工具类:
abstract class BaseArrayCallback<T>(private val clazz: Class<T>) :BaseCallback() { override fun onSuccess(data: String) { val responseData = JSONObject(data) val code = responseData.getInt("code") val message = responseData.getString("message") if (code == 1000) { val disposable = Observable.just(responseData) .map { it.getJSONArray("resp").toString() } .map { JsonUtil.parseArray(it,{ //异常时处理 }) } else { //其他状态时处理 } } abstract fun success(data: ArrayList<T>) }@H_403_0@调用时(伪代码):
LaunchApi.getContactList.execute(object : BaseArrayCallback<ContactEntity>(ContactEntity::class.java) { override fun success(data: ArrayList<ContactEntity>) { //处理数据 })@H_403_0@5.4 复杂数据格式 @H_403_0@使用场景:如用户的筛选数据需要上传到服务器,每次进入筛选界面时先从服务器获取最新数据信息。 @H_403_0@返回的筛选json数据如下所示:
{ "code": 1000,"resp": { "filterdata": [ 321,671 ],}@H_403_0@此时的数据 不同于上面提到的几种Json数据类型,返回的列表中 数据没有key,只有value值 。并不是以键值对(key-value)返回的。 @H_403_0@解析方法: @H_403_0@声明实体类
class FilterEntity { /** 筛选的数据:解析数组对象 为Int 型数据 ArrayList<Int> */ var filterdata = ArrayList<Int>() }@H_403_0@调用方法(伪代码):
HomeApi.getFilterData() .execute(object : CJJObjectCallback<FilterEntity>(FilterEntity::class.java) { override fun success(data: FilterEntity) { //处理数据 } })@H_403_0@当用户选择筛选数据后,需要上传到服务器,伪代码如下:
//上传json示例为:[0,1,2,3,4] val filterList = ArrayList<Int>() //添加int数据 filterList.add(321) filterList.add(671) val jsonData = JsonUtil.toJson(filterList) //上传服务器 HttpTool.put(FILTER_DATA).param("data",jsonData) //Gson转换方法 fun toJson(object: Any): String { var str = "" try { str = gson.toJson(object) } catch (e: Exception) { } return str }@H_403_0@更多地,如果想要 上传多种数据类型,如key-value形式的数据到服务器,伪代码如下:
//json数据示例:{"group":[22,23,24],"brand":[1,4]} // 客户分组筛选 val customerGroupJsonArray = ArrayList<Int>() val map = ArrayMap<String,ArrayList<Int>>() customerGroupList.forEach { customerGroupJsonArray.add(it.id) } map["group"] = customerGroupJsonArray // 品牌筛选 val vehicleBrandJsonArray = ArrayList<Int>() vehicleBrandList.forEach { vehicleBrandJsonArray.add(it.brandId) } map["brand"] = vehicleBrandJsonArray //将map类型的数据转换为json数据 val jsonData = JsonUtil.toJson(map) //上传服务器 HttpTool.put(FILTER_DATA).param("data",jsonData)@H_403_0@6.总结
@H_403_0@本文总结了Android与服务器的交互方式和数据类型,并总结了在实际项目的简单运用,数据格式的运用场景远不止上面提到的几种场景,后期会持续完善,如有不足之处,欢迎指出。 @H_403_0@参考资料: @H_403_0@1.Android手机访问服务器的一种数据交互方法 @H_403_0@2.App架构设计经验谈:接口的设计 @H_403_0@以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。