共计 3373 个字符,预计需要花费 9 分钟才能阅读完成。
背景痛点
在移动端集成 ChatGPT 这类 AI 服务时,开发者常遇到几个典型问题:

- 网络延迟问题:移动网络环境不稳定,可能导致 API 请求超时或响应缓慢
- API 密钥管理:如何安全存储和使用 OpenAI 的 API 密钥,避免泄露风险
- 响应解析复杂性:ChatGPT 返回的 JSON 数据结构较复杂,需要高效解析方案
- 线程管理:网络请求必须在后台线程执行,但 UI 更新又要在主线程完成
技术选型
开发者主要有两种集成方式可选:
- 直接调用 OpenAI API
- 优点:官方支持,功能最全,更新及时
-
缺点:需要自行处理认证、网络请求等底层细节
-
使用第三方 SDK
- 优点:简化了调用流程,提供了更高级的封装
- 缺点:可能存在版本滞后,功能受限
对于大多数 Android 开发者,推荐直接调用官方 API,因为更灵活且可控。
实现步骤
环境准备
首先在 build.gradle 中添加必要依赖:
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
}
然后在 AndroidManifest.xml 中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
API 密钥安全存储
建议使用 Android 的 EncryptedSharedPreferences 存储 API 密钥:
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val sharedPreferences = EncryptedSharedPreferences.create(
context,
"api_keys",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
// 存储密钥
sharedPreferences.edit().putString("OPENAI_API_KEY", "your-api-key").apply()
网络请求实现
使用 OkHttp3 和协程实现异步请求:
suspend fun getChatGPTResponse(prompt: String): String {val client = OkHttpClient()
val mediaType = "application/json".toMediaType()
// 从安全存储中获取 API 密钥
val apiKey = sharedPreferences.getString("OPENAI_API_KEY", "")
val requestBody = """{"model":"gpt-3.5-turbo","messages": [{"role":"user","content":"$prompt"}]
}
""".trimIndent().toRequestBody(mediaType)
val request = Request.Builder()
.url("https://api.openai.com/v1/chat/completions")
.post(requestBody)
.addHeader("Authorization", "Bearer $apiKey")
.addHeader("Content-Type", "application/json")
.build()
return withContext(Dispatchers.IO) {
try {val response = client.newCall(request).execute()
if (!response.isSuccessful) throw IOException("Unexpected code $response")
// 使用 Moshi 解析 JSON 响应
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val adapter = moshi.adapter(ChatGPTResponse::class.java)
val responseBody = response.body?.string() ?: ""
val chatResponse = adapter.fromJson(responseBody)
chatResponse?.choices?.firstOrNull()?.message?.content ?: "No response"} catch (e: Exception) {"Error: ${e.message}"
}
}
}
// 响应数据类
@JsonClass(generateAdapter = true)
data class ChatGPTResponse(val choices: List<Choice>)
data class Choice(val message: Message)
data class Message(val content: String)
性能优化
- 缓存策略:对常见问题的响应进行内存缓存
val cache = LruCache<String, String>(100) // 缓存 100 个最近请求
suspend fun getCachedResponse(prompt: String): String {return cache[prompt] ?: getChatGPTResponse(prompt).also {cache.put(prompt, it)
}
}
- 请求重试机制:对失败请求自动重试
suspend fun <T> retryIO(
times: Int = 3,
initialDelay: Long = 1000, // 1 秒
maxDelay: Long = 10000, // 10 秒
factor: Double = 2.0,
block: suspend () -> T): T {
var currentDelay = initialDelay
repeat(times - 1) {
try {return block()
} catch (e: Exception) {
// 等待时间指数退避
delay(currentDelay)
currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay)
}
}
return block() // 最后一次尝试}
- 响应压缩:启用 OkHttp 的 gzip 压缩
val client = OkHttpClient.Builder()
.addInterceptor(GzipRequestInterceptor()) // 自定义的 gzip 拦截器
.build()
避坑指南
-
处理 429 错误:当收到 ”Too Many Requests” 响应时:
-
检查 API 调用频率是否超过限制
- 实现指数退避重试机制
-
考虑客户端限流
-
避免主线程网络调用:
-
始终在协程或 RxJava 等异步框架中执行网络请求
-
使用
withContext(Dispatchers.IO)确保在 IO 线程执行 -
敏感信息混淆:
-
在
proguard-rules.pro中添加混淆规则保护 API 密钥相关代码 - 避免在日志中打印完整响应数据
延伸思考
- 流式响应处理:
可以修改请求设置stream: true,然后处理分块传输的响应,实现逐字显示效果。
- 本地模型轻量化:
对于某些简单场景,可以考虑使用 TensorFlow Lite 部署精简版语言模型,减少 API 调用依赖。
总结
本文详细介绍了在 Android 应用中集成 ChatGPT API 的完整流程,从环境配置到性能优化,涵盖了开发者可能遇到的主要问题和解决方案。通过合理使用协程、安全存储 API 密钥、优化网络请求等技巧,可以构建出稳定高效的 AI 功能。建议开发者根据具体需求选择合适的实现方案,并持续关注 OpenAI API 的更新。
