中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android客戶端與服務器如何實現數據交互

發布時間:2021-08-26 14:18:31 來源:億速云 閱讀:263 作者:小新 欄目:移動開發

這篇文章主要介紹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) 是一種輕量級的數據交換格式。 易于人閱讀和編寫。同時也易于機器解析和生成。毫無疑問,大家最常用。

本文重點會介紹關于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)

以上是“Android客戶端與服務器如何實現數據交互”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

梅河口市| 五家渠市| 宜君县| 大埔县| 微山县| 梅河口市| 城步| 涪陵区| 兰溪市| 墨脱县| 施甸县| 鄂伦春自治旗| 应用必备| 巩义市| 台东市| 虎林市| 中方县| 清徐县| 连城县| 新郑市| 汝南县| 永兴县| 潮州市| 清新县| 鹤壁市| 大悟县| 临清市| 沙洋县| 杭锦后旗| 武安市| 库尔勒市| 井研县| 资溪县| 马公市| 渑池县| 扎兰屯市| 牟定县| 淮阳县| 疏附县| 正宁县| 漳平市|