android开发分享浅谈Android客户端与服务器的数据交互总结

前言: 本文总结了android客户端与服务器进行交互时,采用restful api +json的交互方式,针对不同的数据形式以及不同的解析方法,如有不足之处,欢迎指

前言:

android开发分享浅谈Android客户端与服务器的数据交互总结总结了android客户端与服务器进行交互时,采用restful api +json的交互方式,针对不同的数据形式以及不同的解析方法,如有不足之处,欢迎指正。

温馨提示:android开发分享浅谈Android客户端与服务器的数据交互总结适合有一定android开发经验的人阅读,如有疑问,欢迎留言讨论。

先了解一下相关的基本概念。

1. android客户端与服务器端通信方式

通信方式主要有http和socket。

  • http通信:即使用http协议进行通信,工作原理是客户端向服务器端发送一条http请求,服务器收到之后先解析客户端的请求,之后会返回数据给客户端,然后客户端再对这些数据进行解析和处理。http连接采取的是“请求—响应”方式,即在请求时建立连接通道,当客户端像服务器端发送请求时,服务器端才能向客户端发送数据。
  • socket通信:socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。通过建立socket连接,可为通信双方的数据传输传提供通道。socket的主要特点有数据丢失率低,使用简单且易于移植。socket类似于peer to peer的连接,一方可随时向另一方喊话。

小结:http和socket都是基于tcp协议的。使用两种通信方式的情况是:

​ 1.使用http的情况:双方不需要时刻保持连接在线,比如客户端资源的获取、文件上传等。

​ 2.使用udp的情况:大部分即时通讯应用(qq、微信)、聊天室、苹果apns等。

2. android客户端与服务器的数据交互方式

主要有三种:

  • 数据流

从web服务器响应到手机终端的数据 一般打包在一个字节数组中,这个字节数据中包含了不同的数据类型,客端端采取java数据流和过虑流的方式从字节数组中取出各种类型的数据。

这种交互方式我在学习android之初用过,实际项目中并没有发现哪家公司在用。这种方式了扩展了android平台在访问web服务器进行交互时的解析数据能力,仅供研究学习。

  • xml

webservice的标准数据格式。

  • protocol buffers

protocol buffers 是一种轻便高效的结构化数据存储格式,支持跨平台。它很适合做数据存储或 rpc 数据交换格式。比 json 最大的优点就是传输的时候数据体积可以压缩很小,传输效率比较高。本人在这个在项目中没有用到过。

  • json

json(javascript object notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。毫无疑问,大家最常用。

android开发分享浅谈Android客户端与服务器的数据交互总结重点会介绍关于json数据格式 的常用格式。

json数据格式 的采用,根据业务情况,一般是团队中的共识。技术的迭代更新,到后期基本都会考虑多个平台的通用性、可移植性和可读性。比如 我们开发团队,有移动端开发(android、ios)、前端开发(h5开发)和后台开发(golang开发)。

关于服务器的开发规范,我们先来了解一下。

服务器开发规范 我们采用的是 restful,restful是目前最流流行的 api设计规范,用于web数据接口的设计。

3. 为什么要使⽤restful api

  • ⾯面向资源(uri),具有解释性;
  • 行为(get / post / put / patch / delete)与资源(uri)分离,更更加轻量量;
  • 数据描述简单,使⽤用json、xml、protocol buffers即可全覆盖,主要使用json;

它的核心原则是定义用少量方法就能操作的命名资源。资源和方法可视为api的名词和动词。

4. http请求方式

  • get :读取(read)
  • post :新建(create)
  • put :更新(update),通常是全部更更新
  • patch :更新(update),通常是部分更更新
  • delete :删除(delete)

项目搭建之始,客户端和服务器一般用 get 和post的方式来交互,随着业务的演进和技术的规范迭代,到后期我们都得按规范来。于是 我们采用了上述几种方式来设计服务器接口,相应地,移动端的请求方式也得与之对应。

至此,不在赘述restful api的设计规范,可自行百度了解更多。

5. json交互数据类型实际中的运用

接口的数据一般都采用json格式进行传输,不过,需要注意的是,json的值只有六种数据类型:

  • number:整数或浮点数
  • string:字符串
  • boolean:true 或 false
  • array:数组包含在方括号[]中
  • object:对象包含在大括号{}中
  • null:空类型

传输的数据类型不能超过这六种数据类型,不能用date数据类型,不同的解析库解析方式不同,可能会导致异常,如果遇到日期的数据,最好的方式就是使用毫秒数表示日期。

5.1 string的数据类型

使用场景:如用户退出登录时,只需要得到返回状态和提示信息即可,不需要返回任何数据。

   {     "code": 1000,     "message": "成功"    }

数据解析工具类:

  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)  }    

调用时(伪代码):

  logoutapi.execute(object : basestringcallback() {            override fun success(msg: string) {     //处理数据            })  

5.2 object数据类型

识别标示为:{}

使用场景:如获取当前用户信息,返回owner实体类,这个类我们可以直接用gson的工具类转换为owner实体类。

  {     "code": 1000,     "message": "成功",     "resp": {      "owner": {       "id": 58180,       "name": "张三",       "idcert": "",       "certtype": 1,       "modifier": "jun5753",       "updatetime": 1567127656436      },     }    }  

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)  }

调用时(伪代码):

  launchapi.getowerinfo.execute(object : baseobjectcallback<ownerentity>(ownerentity::class.java) {       override fun success(data: ownerentity) {        //处理数据       })     

5.3. array数据类型

识别标示为:[]

使用场景:如获取联系人列表,返回的数据是contact列表,如 arraylist<contact >。

  {     "code": 1000,     "message": "成功",     "resp": {      "contact": [       {        "id": 5819,        "name": "来啦",        "phone": "",        "address": "哈哈哈",        "province": "湖南省",        "city": "长沙市",        "area": "芙蓉区",        "modifier": "jun5753",        "isowner": 0,        "updatetime": 1566461377761       },       {        "id": 5835,        "name": "小六",        "phone": "13908258239",        "address": "天安门",        "province": "北京市",        "city": "北京市",        "area": "东城区",        "modifier": "jun5753",        "isowner": 0,        "updatetime": 1567150580553       }      ]     }    }

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, clazz)!! }            .applyscheduler()            .subscribe(                {                  success(it)                },                {                  //异常时处理                })      } else {    //其他状态时处理      }    }    abstract fun success(data: arraylist<t>)  }

调用时(伪代码):

  launchapi.getcontactlist.execute(object : basearraycallback<contactentity>(contactentity::class.java) {       override fun success(data: arraylist<contactentity>) {        //处理数据       })

5.4 复杂数据格式

使用场景:如用户的筛选数据需要上传到服务器,每次进入筛选界面时先从服务器获取最新数据信息。

返回的筛选json数据如下所示:

  {     "code": 1000,     "message": "成功",     "resp": {      "filterdata": [       321,       671      ],           }

此时的数据 不同于上面提到的几种json数据类型,返回的列表中 数据没有key,只有value值 。并不是以键值对(key-value)返回的。

解析方法:

声明实体类

  class filterentity {      /** 筛选的数据:解析数组对象 为int 型数据 arraylist<int> */     var filterdata = arraylist<int>()  }  

 调用方法(伪代码):

  homeapi.getfilterdata()          .execute(object : cjjobjectcallback<filterentity>(filterentity::class.java) {            override fun success(data: filterentity) {            //处理数据            }          })  

当用户选择筛选数据后,需要上传到服务器,伪代码如下:

  //上传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    }       

更多地,如果想要 上传多种数据类型,如key-value形式的数据到服务器,伪代码如下:

  //json数据示例:{"group":[22,23,24],"brand":[1,2,3,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)

6.总结

android开发分享浅谈Android客户端与服务器的数据交互总结总结了android与服务器的交互方式和数据类型,并总结了在实际项目的简单运用,数据格式的运用场景远不止上面提到的几种场景,后期会持续完善,如有不足之处,欢迎指出。

参考资料:

1.android手机访问服务器的一种数据交互方法

2.app架构设计经验谈:接口的设计 

以上就是android开发分享浅谈Android客户端与服务器的数据交互总结的全部内容,希望对大家的学习有所帮助,也希望大家多多支持<计算机技术网(www.ctvol.com)!!>。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/addevelopment/900546.html

(0)
上一篇 2021年10月24日
下一篇 2021年10月24日

精彩推荐