共计 3613 个字符,预计需要花费 10 分钟才能阅读完成。
背景痛点分析
在移动端集成 AI 服务时,开发者常面临几个典型挑战:

- 网络延迟问题:移动网络环境不稳定可能导致 API 响应时间波动,直接影响用户体验
- 响应解析复杂度:AI 服务返回的 JSON 数据结构通常嵌套较深,需要健壮的解析逻辑
- 状态管理困难:对话场景涉及多轮交互,需要维护上下文状态
- 线程安全风险:网络请求必须在后台线程执行,但 UI 更新需回到主线程
技术方案对比
对比当前主流 AI 服务的 Android 集成方案:
| 特性 | Claude API | ChatGPT SDK |
|---|---|---|
| 集成复杂度 | 中等(需自行封装) | 低(官方 SDK) |
| 响应速度 | 快(流式响应支持) | 中等 |
| 上下文管理 | 需手动维护 | 内置支持 |
| 移动端优化 | 需自定义实现 | 部分内置 |
核心实现步骤
1. 项目基础配置
首先在 build.gradle 中添加必要依赖:
dependencies {
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.10.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
}
2. 安全存储 API 密钥
避免硬编码密钥,推荐使用local.properties:
claude.api.key=your_api_key_here
通过 Gradle 脚本读取:
fun getApiKey(): String {val properties = Properties()
val localProperties = rootProject.file("local.properties")
if (localProperties.exists()) {localProperties.inputStream().use {properties.load(it) }
}
return properties.getProperty("claude.api.key") ?: ""
}
3. Retrofit 客户端构建
创建带认证的 OkHttpClient:
private fun createHttpClient(): OkHttpClient {return OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer ${getApiKey()}")
.addHeader("Content-Type", "application/json")
.build()
chain.proceed(request)
}
.addInterceptor(HttpLoggingInterceptor().apply {level = HttpLoggingInterceptor.Level.BASIC})
.build()}
4. ViewModel 层实现
采用协程处理异步请求:
class ChatViewModel : ViewModel() {private val repository = ChatRepository()
private val _messages = MutableStateFlow<List<ChatMessage>>(emptyList())
val messages: StateFlow<List<ChatMessage>> = _messages
fun sendMessage(prompt: String) = viewModelScope.launch {
try {_messages.update { it + ChatMessage(user = prompt, isUser = true) }
repository.getClaudeResponse(prompt)
.collect { response ->
_messages.update { messages ->
if (messages.last().isUser) {
messages + ChatMessage(
user = response,
isUser = false
)
} else {messages.dropLast(1) + ChatMessage(user = messages.last().user + response,
isUser = false
)
}
}
}
} catch (e: Exception) {// 错误处理逻辑}
}
}
5. 流式响应处理
实现响应数据流解析:
interface ClaudeApiService {@POST("v1/complete")
@Streaming
suspend fun getCompletion(@Body request: CompletionRequest): Response<ResponseBody>
}
suspend fun parseStreamingResponse(response: Response<ResponseBody>): Flow<String> {
return callbackFlow {val source = response.body()?.source()
source?.let {while (!source.exhausted()) {val line = source.readUtf8Line() ?: continue
if (line.startsWith("data:")) {val json = line.substring(6)
try {val data = Json.decodeFromString<CompletionChunk>(json)
send(data.completion)
} catch (e: Exception) {// 解析错误处理}
}
}
}
close()}
}
避坑指南
1. 网络权限配置
确保 AndroidManifest.xml 包含:
<uses-permission android:name="android.permission.INTERNET" />
2. 后台线程限制
使用协程时注意 Dispatchers 切换:
viewModelScope.launch(Dispatchers.IO) {
// 网络请求
withContext(Dispatchers.Main) {// UI 更新}
}
3. 上下文管理优化
建议维护对话历史队列:
class ConversationManager(private val maxHistory: Int = 5) {private val history = LinkedList<ChatMessage>()
fun addMessage(message: ChatMessage) {if (history.size >= maxHistory) {history.removeFirst()
}
history.add(message)
}
fun getContextPrompt(): String {return history.joinToString("\n") { msg ->
if (msg.isUser) "User: ${msg.user}" else "Assistant: ${msg.user}"
}
}
}
性能优化建议
1. OkHttp 缓存配置
private fun createHttpClient(): OkHttpClient {
val cacheSize = 10 * 1024 * 1024 // 10MB
val cache = Cache(File(context.cacheDir, "http_cache"), cacheSize.toLong())
return OkHttpClient.Builder()
.cache(cache)
// 其他配置...
.build()}
2. 请求体压缩
启用 Gzip 压缩:
.addInterceptor { chain ->
val originalRequest = chain.request()
val compressedRequest = originalRequest.newBuilder()
.header("Accept-Encoding", "gzip")
.method(originalRequest.method, originalRequest.body)
.build()
chain.proceed(compressedRequest)
}
延伸思考
可以考虑进一步实现:
- 消息持久化:使用 Room 数据库保存对话历史
- 本地缓存策略:对常见问题建立回答缓存
- 离线模式:当网络不可用时提供基础回复
- 性能监控:添加 API 响应时间统计
完整示例项目可参考 GitHub 仓库(需替换为实际仓库地址)。在实际开发中,建议根据具体业务需求调整上下文管理策略和错误处理机制。
正文完
发表至: 未分类
近三天内
