千问3.5-9B Android Studio移动端AI应用开发入门
本文介绍了如何在星图GPU平台上自动化部署千问3.5-9B镜像,快速开发Android Studio移动端AI应用。该平台简化了部署流程,使开发者能轻松集成千问3.5-9B模型,实现智能聊天功能等移动端AI场景,提升开发效率。
千问3.5-9B Android Studio移动端AI应用开发入门
1. 移动端AI应用开发新选择
最近在开发移动端AI应用时,发现千问3.5-9B模型是个不错的选择。这个模型体积适中,响应速度快,特别适合在移动端通过API调用。今天我就来分享下,如何在Android Studio中快速开发一个集成千问3.5-9B的聊天应用。
相比直接在服务器部署大模型,这种前后端分离的方式有几个明显优势:一是手机不需要承担模型推理的算力负担;二是可以随时切换不同模型服务;三是应用包体不会因为内置模型而变得臃肿。
2. 开发环境准备
2.1 Android Studio下载与安装
首先需要准备好开发环境。如果你还没安装Android Studio,可以到官网下载最新版本。安装过程很简单,基本上就是一路"下一步"。不过有几点需要注意:
- 确保电脑满足最低配置要求(至少8GB内存,推荐16GB)
- 安装时勾选Android SDK和必要的工具链
- 安装完成后,记得通过SDK Manager安装对应版本的Android SDK
2.2 创建新项目
打开Android Studio后,选择"Start a new Android Studio project"。在模板选择界面,推荐使用"Empty Activity",这样可以从零开始构建我们的AI聊天应用。
项目配置时要注意:
- 语言选择Kotlin(当然你也可以用Java,但Kotlin现在是官方推荐语言)
- 最低API级别建议设为24(Android 7.0),这样可以覆盖大多数设备
- 其他设置保持默认即可
3. 基础界面搭建
3.1 设计聊天界面
我们的AI聊天应用需要几个基本组件:
- 一个显示对话历史的RecyclerView
- 底部的输入框和发送按钮
- 简单的消息气泡样式
在res/layout/activity_main.xml中,可以这样布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chatRecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/messageEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="输入你的问题..."/>
<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"/>
</LinearLayout>
</LinearLayout>
3.2 实现消息适配器
为了在RecyclerView中显示聊天消息,我们需要创建一个消息适配器:
class MessageAdapter(private val messages: MutableList<Message>) :
RecyclerView.Adapter<MessageAdapter.MessageViewHolder>() {
inner class MessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val messageText: TextView = itemView.findViewById(R.id.messageText)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
val layout = if (viewType == MSG_TYPE_SENT) {
R.layout.item_message_sent
} else {
R.layout.item_message_received
}
val view = LayoutInflater.from(parent.context).inflate(layout, parent, false)
return MessageViewHolder(view)
}
override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
holder.messageText.text = messages[position].content
}
override fun getItemCount() = messages.size
override fun getItemViewType(position: Int) = messages[position].type
}
4. 集成千问3.5-9B API
4.1 添加网络请求依赖
在app/build.gradle文件中添加Retrofit和Gson依赖:
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
}
4.2 创建API服务接口
定义与千问3.5-9B后端服务通信的接口:
interface QwenAIService {
@POST("/v1/chat/completions")
suspend fun chatCompletion(
@Body request: ChatRequest
): Response<ChatResponse>
}
data class ChatRequest(
val model: String = "qwen-3.5-9B",
val messages: List<Message>,
val temperature: Float = 0.7f
)
data class ChatResponse(
val choices: List<Choice>
)
data class Choice(
val message: Message
)
data class Message(
val role: String,
val content: String
)
4.3 实现网络请求
创建一个Retrofit实例并实现API调用:
object QwenAIClient {
private const val BASE_URL = "https://your-qwen-api-server.com"
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(
OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
)
.build()
}
val service: QwenAIService by lazy {
retrofit.create(QwenAIService::class.java)
}
}
5. 实现完整聊天流程
5.1 发送消息处理
在MainActivity中实现发送消息的逻辑:
class MainActivity : AppCompatActivity() {
private lateinit var adapter: MessageAdapter
private val messages = mutableListOf<Message>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
adapter = MessageAdapter(messages)
chatRecyclerView.adapter = adapter
chatRecyclerView.layoutManager = LinearLayoutManager(this)
sendButton.setOnClickListener {
val userMessage = messageEditText.text.toString()
if (userMessage.isNotBlank()) {
// 添加用户消息到列表
addMessage(Message(role = "user", content = userMessage))
messageEditText.text.clear()
// 发送到AI并获取回复
CoroutineScope(Dispatchers.IO).launch {
try {
val response = QwenAIClient.service.chatCompletion(
ChatRequest(messages = messages)
)
if (response.isSuccessful) {
val aiMessage = response.body()?.choices?.first()?.message
aiMessage?.let {
withContext(Dispatchers.Main) {
addMessage(it)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
}
private fun addMessage(message: Message) {
messages.add(message)
adapter.notifyItemInserted(messages.size - 1)
chatRecyclerView.smoothScrollToPosition(messages.size - 1)
}
}
5.2 实现消息缓存
为了提升用户体验,我们可以添加简单的消息缓存功能:
object ChatCache {
private const val PREFS_NAME = "ChatPrefs"
private const val KEY_MESSAGES = "messages"
fun saveMessages(context: Context, messages: List<Message>) {
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
val json = Gson().toJson(messages)
prefs.edit().putString(KEY_MESSAGES, json).apply()
}
fun loadMessages(context: Context): List<Message> {
val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
val json = prefs.getString(KEY_MESSAGES, null)
return if (json != null) {
val type = object : TypeToken<List<Message>>() {}.type
Gson().fromJson(json, type) ?: emptyList()
} else {
emptyList()
}
}
}
然后在Activity中适当位置调用保存和加载方法:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...其他代码...
// 加载历史消息
messages.addAll(ChatCache.loadMessages(this))
adapter.notifyDataSetChanged()
}
override fun onPause() {
super.onPause()
// 保存当前对话
ChatCache.saveMessages(this, messages)
}
6. 优化与改进建议
现在我们已经完成了一个基本的千问3.5-9B移动端集成应用,但还有几个可以优化的地方:
首先是网络状态处理。实际应用中应该检查网络连接,并在离线时给出提示。可以添加一个网络状态监听器:
private fun checkNetworkConnection(): Boolean {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
}
其次是加载状态提示。在等待AI回复时,可以显示一个加载动画,提升用户体验。最简单的方式是添加一个ProgressBar到布局中,并在请求开始和结束时控制其可见性。
最后是错误处理。网络请求可能会失败,应该给用户适当的反馈。可以在catch块中添加Toast提示:
catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(this@MainActivity, "请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐



所有评论(0)