Preface:
This article summarizes the interaction method of RESTful API + Json when interacting with Android clients and servers, and provides different data forms and different parsing methods. If there are any shortcomings, please feel free to correct them.
Warm reminder: This article is suitable for people with certain Android development experience. If you have any questions, please leave a message to discuss.
Let’s first understand the relevant basic concepts.
1. How to communicate between Android client and server
The communication methods mainly include HTTP and Socket.
- HTTP communication: That is, communication is done using the HTTP protocol. The working principle is that the client sends an HTTP request to the server. After receiving it, the server first parses the client's request, and then returns the data to the client, and then the client parses and processes the data. HTTP connection adopts the "request-response" method, that is, establish a connection channel during request. When the client sends a request like the server, the server can send data to the client.
- Socket communication: Socket is also known as sockets, which provides a port for communication with the outside world within the program, that is, port communication. By establishing a socket connection, a channel can be provided for data transmission between both parties to the communication. The main features of Socket are low data loss rate, simple use and easy to port. Socket is similar to the connection of peer to peer, one party can shout to the other party at any time.
Summary: HTTP and Socket are both based on the TCP protocol. The situation where two communication methods are:
1. When using HTTP: Both parties do not need to keep the connection online at all times, such as obtaining client resources, uploading files, etc.
2. UDP usage: 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 flow
Data responding from a web server to a mobile terminal is generally packaged in a byte array, which contains different data types. The client uses Java data stream and overthinking stream to retrieve various types of data from the byte array.
I used this interactive method when I first learned Android, but I didn't find any company using it in the actual project. This method expands the Android platform's ability to parse data when accessing Web servers for interaction, and is for research and learning only.
- XML
Webservice's standard data format.
- 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 formats. The biggest advantage over JSON is that the data volume can be compressed very small during transmission and has relatively high transmission efficiency. I haven't used this in the project.
- JSON
JSON (JavaScript Object Notation) is a lightweight data exchange format. Easy to read and write. It is also easy to analyze and generate machine. There is no doubt that everyone uses it most often.
This article will focus on the commonly used formats about json data format.
The adoption of json data format is generally a consensus among the team based on business conditions. The iterative update of technology will basically consider the universality, portability and readability of multiple platforms in the later stage. For example, our development team includes mobile development (Android, iOS), front-end development (H5 development) and back-end development (golang development).
Let’s first understand the server development specifications.
Server Development Specification We use RESTful, which is the most popular API design specification currently used for the design of web data interfaces.
3. Why use RESTful API
- Resource-oriented (URI), explanatory;
- Behavior (GET/POST/PUT/PATCH/DELETE) is separated from resources (URI), making it lighter;
- The data description is simple, and it can be fully covered by using JSON, XML, and Protocol Buffers, mainly using JSON;
Its core principle is to define named resources that can be operated with a small number of methods. Resources and methods can be regarded as nouns and verbs for APIs.
4. http request method
- GET: Read (Read)
- POST: Create
- PUT: Update, usually all updates
- PATCH: Update, usually partially updated
- DELETE: Delete
At the beginning of the project construction, clients and servers generally interact in the form of Get and Post. With the evolution of the business and the standardization of technology, we have to follow the specifications in the later stage. Therefore, we used the above methods to design the server interface, and accordingly, the request method of the mobile terminal must also correspond to it.
At this point, I will not elaborate on the design specifications of the RESTful API, but you can learn more on Baidu.
5. The actual application of Json interactive data types
The data of the interface is generally transmitted in JSON format. However, it should be noted that there are only six data types of JSON values:
- Number: integer or floating point number
- String: String
- Boolean: true or false
- Array: Array is included in square brackets[]
- Object: Object is contained in braces {}
- Null: empty type
The data types transmitted cannot exceed these six data types, and the Date data type cannot be used. Different parsing libraries have different methods of parsing, which may cause exceptions. If you encounter date data, the best way is to use milliseconds to represent the date.
5.1 String's data type
Usage scenario: If the user logs out, he only needs to get the return status and prompt information, and no data is needed.
{ "code": 1000, "message": "success" }
Data analysis tool class:
abstract class BaseStringCallback: BaseCallback() { override fun onSuccess(data: String) { val responseData = JSONObject(data) val code = ("code") val message = ("message") if (code == 1000) { success(message) } else { //Other status } } abstract fun success(msg: String) }
When calling (pseudocode):
(object : BaseStringCallback() { override fun success(msg: String) { // Process data })
5.2 Object data type
Identification label is: {}
Usage scenario: For example, if you get the current user information, return the owner entity class. We can directly convert this class to the owner entity class using Gson's tool class.
{ "code": 1000, "message": "success", "resp": { "owner": { "id": 58180, "name": "Zhang San", "idCert": "", "certType": 1, "modifier": "jun5753", "updateTime": 1567127656436 }, } }
Convert Json data 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 = ("code") val message = ("message") if (code == 1000) { val disposable = (responseData) .map { ("resp").toString() } .map { (it, clazz)!! } .applyScheduler() .subscribe( { success(it) }, { //Exception is handled }) } else { //Processing in other states } } abstract fun success(data: T) }
When calling (pseudocode):
(object : BaseObjectCallback<OwnerEntity>(OwnerEntity::) { override fun success(data: OwnerEntity) { // Process data })
5.3. Array data type
The identification mark is: []
Usage scenario: If you get a contact list, the returned data is a contact list, such as ArrayList<contact>.
{ "code": 1000, "message": "success", "resp": { "contact": [ { "id": 5819, "name": "Come", "phone": "", "address": "Hahaha", "province": "Hunan Province", "city": "Changsha City", "area": "Furong District", "modifier": "jun5753", "isOwner": 0, "updateTime": 1566461377761 }, { "id": 5835, "name": "Xiao Liu", "phone": "13908258239", "address": "* Square", "province": "Beijing", "city": "Beijing", "area": "Dongcheng District", "modifier": "jun5753", "isOwner": 0, "updateTime": 1567150580553 } ] } }
Convert Json data 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 = ("code") val message = ("message") if (code == 1000) { val disposable = (responseData) .map { ("resp").toString() } .map { (it, clazz)!! } .applyScheduler() .subscribe( { success(it) }, { //Exception is handled }) } else { //Processing in other states } } abstract fun success(data: ArrayList<T>) }
When calling (pseudocode):
(object : BaseArrayCallback<ContactEntity>(ContactEntity::) { override fun success(data: ArrayList<ContactEntity>) { // Process data })
5.4 Complex data format
Usage scenario: If the user's filtering data needs to be uploaded to the server, each time you enter the filtering interface, you will first obtain the latest data information from the server.
The returned filtered json data is as follows:
{ "code": 1000, "message": "success", "resp": { "filterdata": [ 321, 671 ], }
The data at this time is different from the Json data types mentioned above. The data in the returned list has no key, only a value value. Not returned as key-value pairs.
Analysis method:
Declare entity class
class FilterEntity { /** Filtered data: parse array object as Int type data ArrayList<Int> */ var filterdata = ArrayList<Int>() }
Calling method (pseudocode):
() .execute(object : CJJObjectCallback<FilterEntity>(FilterEntity::) { override fun success(data: FilterEntity) { // Process data } })
When the user chooses to filter the data, it needs to be uploaded to the server. The pseudo-code is as follows:
//The example of uploading json is: [0,1,2,3,4]val filterList = ArrayList<Int>() //Add int data (321) (671) val jsonData = (filterList) //Upload the server (FILTER_DATA).param("data", jsonData) //Gson conversion method fun toJson(object: Any): String { var str = "" try { str = (object) } catch (e: Exception) { } return str }
More specifically, if you want to upload data in multiple data types, such as key-value form, to the server, the pseudo-code is as follows:
//json data example: {"group":[22,23,24],"brand":[1,2,3,4]} // Customer group filteringval customerGroupJsonArray = ArrayList<Int>() val map = ArrayMap<String, ArrayList<Int>>() { () } map["group"] = customerGroupJsonArray // Brand filtering val vehicleBrandJsonArray = ArrayList<Int>() { () } map["brand"] = vehicleBrandJsonArray //Convert map type data to json data val jsonData = (map) //Upload the server (FILTER_DATA).param("data", jsonData)
6. Summary
This article summarizes the interaction methods and data types between Android and servers, and summarizes the simple application of actual projects. The application scenarios of data formats are far more than the several scenarios mentioned above, and will continue to be improved in the later stage. If there are any shortcomings, please point them out.
References:
1.A data interaction method for Android mobile phone accessing servers
2.Experience in App Architecture Design: Interface Design
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.