凌峰创科服务平台

Android客户端与服务器如何高效通信?

核心概念与架构

在开始之前,我们先理解几个基本概念:

Android客户端与服务器如何高效通信?-图1
(图片来源网络,侵删)
  1. 客户端:指你的 Android App,它的职责是:

    • 向服务器发起请求。
    • 接收服务器返回的数据。
    • 将数据解析成 App 可以使用的对象(如 Java/Kotlin 对象)。
    • 将用户操作和输入封装成请求发送给服务器。
  2. 服务器:通常指一个 Web 服务器,上面运行着后端应用程序,它的职责是:

    • 接收客户端的请求。
    • 进行业务逻辑处理(如数据库查询、计算等)。
    • 将处理结果格式化后返回给客户端。
  3. 通信协议:客户端和服务器之间“对话”的语言,目前最主流的是 HTTP/HTTPS

  4. 数据格式:客户端和服务器之间交换数据的“语法”,常见格式有:

    Android客户端与服务器如何高效通信?-图2
    (图片来源网络,侵删)
    • JSON (JavaScript Object Notation):轻量级、易于人阅读和编写,也易于机器解析和生成,是目前最主流的选择。
    • XML (eXtensible Markup Language):曾经非常流行,但现在逐渐被 JSON 替代,因为它更冗重。
    • Protocol Buffers / gRPC:由 Google 提出,性能更高、更高效,适用于对性能和带宽有极高要求的场景。
  5. 网络请求库:直接使用 Java 的 HttpURLConnection 或 Android 的 HttpClient 是非常繁琐和底层的,开发者通常会使用第三方库来简化网络请求,这些库封装了复杂的细节,提供了更简洁的 API。


主流的通信方案(从简单到复杂)

HTTP + JSON + OkHttp + Retrofit (最主流、推荐)

这是目前 Android 开发领域的事实标准,它是一个组合拳,各司其职,非常强大。

  • OkHttp:一个高效的 HTTP 客户端,它负责底层的网络连接、线程管理、缓存、拦截器等,Retrofit 内部就是基于 OkHttp 来执行网络请求的。
  • Retrofit:一个类型安全的 HTTP 客户端,它将 HTTP API 转换成一个 Java/Kotlin 接口,通过注解来描述请求参数、URL、方法等,你只需要定义接口,Retrofit 就会帮你实现它,并返回一个对象。

工作流程:

  1. 定义 API 接口:使用 Retrofit 的注解定义你的网络请求。
    interface ApiService {
        @GET("users/{id}")
        suspend fun getUser(@Path("id") userId: String): Response<User> // 使用协程和 Flow
    }
  2. 创建 Retrofit 实例
    val retrofit = Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .addConverterFactory(GsonConverterFactory.create()) // 用于 JSON 解析
        .build()
  3. 生成接口实现
    val apiService = retrofit.create(ApiService::class.java)
  4. 发起请求
    // 在协程中调用
    lifecycleScope.launch {
        try {
            val response = apiService.getUser("123")
            if (response.isSuccessful) {
                val user = response.body()
                // 更新 UI
            } else {
                // 处理错误
            }
        } catch (e: Exception) {
            // 处理网络异常等
        }
    }

优点

Android客户端与服务器如何高效通信?-图3
(图片来源网络,侵删)
  • 类型安全:编译时就能检查出 URL、参数等错误。
  • 代码简洁:将网络请求逻辑与业务逻辑分离,代码非常清晰。
  • 功能强大:支持同步/异步请求、拦截器、RxJava/Flow/协程等。
  • 社区活跃:文档完善,问题解决方案多。

WebSocket (实时双向通信)

当你需要服务器能主动向客户端推送数据时,WebSocket 是最佳选择,聊天应用、实时股票行情、在线游戏等。

  • 特点:建立一个长连接,客户端和服务器可以随时互相发送消息,而无需客户端轮询。

实现方式: 可以使用 OkHttp 自带的 WebSocket API,或者更高级的库如 AndroidAsyncSocket.IO (Node.js 生态常用)。

工作流程

  1. 客户端向服务器发起 WebSocket 连接握手。
  2. 握手成功后,建立一个持久连接。
  3. 客户端通过 send() 方法发送消息。
  4. 客户端通过重写 onMessage() 方法接收服务器的推送消息。
  5. 当不再需要时,关闭连接。

MQTT (物联网领域的轻量级消息协议)

MQTT (Message Queuing Telemetry Transport) 是一种基于发布/订阅模式的“轻量级”消息协议,非常适合物联网、移动设备等网络带宽有限或不可靠的场景。

  • 特点:极低开销、低带宽、支持 QoS (服务质量) 等级,有一个中心化的 Broker (代理服务器)。

工作流程

  1. 设备(客户端)连接到 MQTT Broker。
  2. 设备可以“订阅”(Subscribe)一个或多个“主题”(Topic)。
  3. 任何设备都可以向某个“主题”“发布”(Publish)消息。
  4. Broker 会将消息转发给所有订阅了该主题的设备。

实现库:Eclipse Paho, HiveMQ MQTT Client


完整通信流程详解

我们以最主流的 HTTP + Retrofit 为例,走一遍完整的流程。

服务器端 (假设是 RESTful API)

  • 设计 API 接口:定义好 URL、HTTP 方法、请求参数、返回数据格式。

    • 获取用户信息GET /api/v1/users/{id},返回 JSON 格式的用户数据。
    • 登录POST /api/v1/login,请求体是 { "username": "...", "password": "..." },返回 Token。
  • 后端实现:使用 Node.js (Express), Java (Spring Boot), Python (Django/Flask) 等技术栈实现上述接口,并处理数据库交互。

Android 客户端

第一步:添加依赖

app/build.gradle.kts (或 build.gradle) 文件中添加:

// OkHttp 和 Retrofit
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") // JSON 转换器
// 协程支持 (推荐)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")

第二步:添加网络权限

app/src/main/AndroidManifest.xml 中:

<uses-permission android:name="android.permission.INTERNET" />
<application ...>
    ...
</application>

注意:从 Android 9 (API 28) 开始,默认禁止 HTTP (明文) 流量,只允许 HTTPS,如果你的服务器是 HTTP,需要在 application 标签下添加: android:usesCleartextTraffic="true"

第三步:创建数据模型

根据服务器返回的 JSON 结构,创建对应的 Kotlin 数据类。

// User.kt
data class User(
    val id: String,
    val name: String,
    val email: String
)

第四步:定义 API 接口

interface ApiService {
    @GET("users/{id}")
    suspend fun getUser(@Path("id") userId: String): Response<User>
}

第五步:创建 Retrofit 单例

object RetrofitClient {
    private const val BASE_URL = "https://api.example.com/"
    val instance: ApiService by lazy {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(OkHttpClient.Builder().build()) // 可以在这里添加拦截器
            .build()
        retrofit.create(ApiService::class.java)
    }
}

第六步:在 ViewModel 或 Activity/Fragment 中发起请求

// 在 ViewModel 中使用协程发起请求
class UserViewModel : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user
    fun fetchUser(userId: String) {
        viewModelScope.launch { // viewModelScope 会在 ViewModel 销毁时自动取消协程
            try {
                val response = RetrofitClient.instance.getUser(userId)
                if (response.isSuccessful) {
                    _user.postValue(response.body())
                } else {
                    // 处理 API 返回的错误,如 404, 500
                    Log.e("UserViewModel", "Error: ${response.code()}")
                }
            } catch (e: Exception) {
分享:
扫描分享到社交APP
上一篇
下一篇