Summary of data interaction between Android client and server

  • 2021-11-13 02:36:47
  • OfStack

Foreword:

This paper summarizes the interaction between Android client and server, which adopts RESTful API + Json interaction mode, aiming at different data forms and different analysis methods. If there are shortcomings, please correct them.

Warm Tip: This article is suitable for people who have experience in developing Android. If you have any questions, please leave a message for discussion.

First understand the basic concepts related to 1.

1. Communication mode between Android client and server

The main communication modes are HTTP and Socket.

HTTP communication: That is, HTTP protocol is used for communication. The working principle is that the client sends an HTTP request to the server. After receiving it, the server first analyzes the client's request, and then returns data to the client, and then the client analyzes and processes these data. HTTP connection adopts a "request-response" mode, that is, a connection channel is established when requesting, and when the client sends a request like the server, the server can send data to the client. Socket Communication: Socket, also known as socket, provides a port to communicate with the outside world inside the program, that is, port communication. By establishing socket connection, it can provide a channel for data transmission between the two parties. The main features of Socket are low data loss rate, easy to use and easy to transplant. Socket is similar to the connection of peer to peer, and one party can shout to the other party at any time.

Summary: Both HTTP and Socket are based on TCP protocol. Two modes of communication are used:

1. Using HTTP: Both parties do not need to keep connected online at all times, such as obtaining client resources and uploading files.

2. Use of UDP: Most instant messaging applications (QQ, WeChat), chat rooms, Apple APNs, etc.

2. Data interaction between Android client and server

There are three main types:

Data stream

The data from the web server to the mobile phone terminal is packaged in a byte array, and the byte data contains different data types. The guest end takes out various types of data from the byte array by means of Java data stream and over-filtering stream.

I used this interaction at the beginning of learning Android, but I didn't find any company using it in the actual project. This way expands the ability of analyzing data when Android platform accesses Web server for interaction, which is only for research and learning.

XML

Standard data format for Webservice.

Protocol Buffers

Protocol Buffers is a lightweight and efficient structured data storage format that supports cross-platform. It is very suitable for data storage or RPC data exchange format. Compared with JSON, the biggest advantage is that the data volume can be compressed very little and the transmission efficiency is relatively high. I didn't use it in this project.

JSON

JSON (JavaScript Object Notation) is a lightweight data exchange format. Easy to read and write. At the same time, it is easy to analyze and generate by machine. There is no doubt that people use it most often.

This article focuses on the common formats of json data format.

The adoption of json data format is generally the consensus of the team according to the business situation. In the iterative update of technology, the universality, portability and readability of multiple platforms will basically be considered in the later stage. For example, our development team has mobile development (Android, iOS), front-end development (H5 development) and back-end development (golang development).

About the server development specification, let's first understand 1.

Server development specification we use is RESTful, RESTful is the current most popular API design specification, for web data interface design.

3. Why do you want to make a hundred RESTful API

Resource-oriented (URI), explanatory; Separate (GET/POST/PUT/PATCH/DELETE) from resources (URI), and add lighter weight; The data description is simple, so that JSON, XML, Protocol and Buffers can be fully covered, mainly using JSON;;

Its core principle is to define named resources that can be operated by a few methods. Resources and methods can be regarded as nouns and verbs of API.

4. http Request Mode

GET: Read (Read) POST: New (Create) PUT: New (Update), usually all new PATCH: New (Update), usually partially newer DELETE: Delete (Delete)

At the beginning of the project construction, the client and server 1 generally interact in the way of Get and Post. With the evolution of business and the iteration of technical specifications, we have to follow the specifications in the later stage. So we use the above-mentioned ways to design the server interface, and accordingly, the request mode of the mobile terminal has to correspond to it.

At this point, I won't repeat the design specifications of RESTful API, but I can learn more about it by Baidu.

5. Practical application of Json interactive data type

Data 1 of the interface is generally transmitted in JSON format, but it should be noted that there are only six data types for JSON values:

Number: Integer or Floating Point String: String Boolean: true or false Array: Array enclosed in square brackets [] Object: Object enclosed in curly braces {} Null: Empty type

The transmitted data types can't exceed these six data types, and Date data types can't be used. Different parsing libraries have different parsing methods, which may lead to exceptions. If you encounter date data, the best way is to use milliseconds to represent the date.

5.1 Data Types for String

Usage scenario: When the user logs out, he only needs to get the return status and prompt information, and does not need to return any data.


 {
   "code": 1000,
   "message": " Success "
  }

Data parsing tool class:


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 {
      // Other states 
    }
  }

  abstract fun success(msg: String)
}

When called (pseudocode):


LogoutApi.execute(object : BaseStringCallback() {
          override fun success(msg: String) {
   // Processing data 
          } ) 

5.2 Object data type

The identification mark is: {}

Usage scenario: If you get the current user information, return the owner entity class, which we can directly convert into owner entity class with the tool class of Gson.


{
   "code": 1000,
   "message": " Success ",
   "resp": {
    "owner": {
     "id": 58180,
     "name": " Zhang 3",
     "idCert": "",
     "certType": 1,
     "modifier": "jun5753",
     "updateTime": 1567127656436
    },
   }
  }

Json data conversion to entity class tool class:


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)
              },
              {
                // Handling on exception 
              })
     
    } else {
     // Other states 
    }
  }

  abstract fun success(data: T)
}

When called (pseudocode):


LaunchApi.getOwerInfo.execute(object : BaseObjectCallback<OwnerEntity>(OwnerEntity::class.java) {  
   override fun success(data: OwnerEntity) { 
     // Processing data   
   })
 

5.3. Array data types

The identification mark is: []

Usage scenario: If you get a contact list, the returned data is an contact list, such as ArrayList < contact > .


{
   "code": 1000,
   "message": " Success ",
   "resp": {
    "contact": [
     {
      "id": 5819,
      "name": " Coming ",
      "phone": "",
      "address": " Ha ha ha ",
      "province": " Hunan Province ",
      "city": " Changsha City ",
      "area": " Furong District ",
      "modifier": "jun5753",
      "isOwner": 0,
      "updateTime": 1566461377761
     },
     {
      "id": 5835,
      "name": " Small 6",
      "phone": "13908258239",
      "address": " Tian'anmen Square ",
      "province": " Beijing ",
      "city": " Beijing ",
      "area": " Dongcheng District ",
      "modifier": "jun5753",
      "isOwner": 0,
      "updateTime": 1567150580553
     }
    ]
   }
  }

Json Data Transformation to Entity Class List Tool Class:


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)
              },
              {
                // Handling on exception 
              })
    } else {
  // Other states 
    }
  }
  abstract fun success(data: ArrayList<T>)
}

When called (pseudocode):


LaunchApi.getContactList.execute(object : BaseArrayCallback<ContactEntity>(ContactEntity::class.java) {  
   override fun success(data: ArrayList<ContactEntity>) { 
     // Processing data   
   })

5.4 Complex data formats

Usage scenario: If the user's filtering data needs to be uploaded to the server, the latest data information should be obtained from the server every time he enters the filtering interface.

The filtered json data returned is as follows:


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

The data at this point is different from the several Json data types mentioned above, and the data in the returned list has no key, only value value. Is not returned as a key-value pair (key-value).

Parsing method:

Declare Entity Class


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 {
      // Other states 
    }
  }

  abstract fun success(msg: String)
}

0

Invoke the method (pseudocode):


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 {
      // Other states 
    }
  }

  abstract fun success(msg: String)
}

1

When the user chooses to filter the data, it needs to be uploaded to the server. The pseudo code is as follows:


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 {
      // Other states 
    }
  }

  abstract fun success(msg: String)
}

2

Moreover, if you want to upload data of multiple data types, such as key-value, to the server, the pseudo code is as follows:


//json Data example: {"group":[22,23,24],"brand":[1,2,3,4]}

//  Customer grouping screening 
val customerGroupJsonArray = ArrayList<Int>()

 val map = ArrayMap<String, ArrayList<Int>>()
  customerGroupList.forEach {
    customerGroupJsonArray.add(it.id)
   }
  map["group"] = customerGroupJsonArray

  //  Brand selection 
  val vehicleBrandJsonArray = ArrayList<Int>()
  vehicleBrandList.forEach {
    vehicleBrandJsonArray.add(it.brandId)
  }
  map["brand"] = vehicleBrandJsonArray

 // Will map Data of type is converted to json Data 
  val jsonData = JsonUtil.toJson(map)

 // Upload server 
  HttpTool.put(FILTER_DATA).param("data", jsonData)

6. Summary

This paper summarizes the interaction mode and data type between Android and the server, and summarizes the simple application in actual projects. The application scenarios of data format are far more than those mentioned above, and will continue to be improved in the later period. If there are any shortcomings, please point out them.

References:

1. A data interaction method for Android mobile phone accessing server

2. Experience of App architecture design: interface design


Related articles: