如何实现Kotlin安卓应用与Django项目的双向数据交互?
Django后端与Kotlin Android App数据交互实现方案
针对你需要的「安卓输入数字→Django后端处理(查库/新增)→返回结果」流程,结合你已有Django开发经验,给出以下具体实现步骤:
一、Django后端实现
1. 定义数据库模型
创建对应存储数字记录的Model:
from django.db import models class NumberRecord(models.Model): number = models.IntegerField(unique=True) info = models.CharField(max_length=255, default="数字对应信息") created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Number {self.number}"
2. 用DRF编写API接口
推荐使用Django REST Framework(DRF)快速构建API,先安装DRF并配置,然后实现处理逻辑:
序列化器(serializers.py)
from rest_framework import serializers from .models import NumberRecord class NumberRecordSerializer(serializers.ModelSerializer): class Meta: model = NumberRecord fields = ['id', 'number', 'info', 'created_at']
API视图(views.py)
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import NumberRecord from .serializers import NumberRecordSerializer class NumberHandlerAPI(APIView): def post(self, request): input_number = request.data.get('number') # 校验输入 if not input_number or not isinstance(input_number, int): return Response({"error": "请输入有效的整数"}, status=status.HTTP_400_BAD_REQUEST) # 查询或创建记录(get_or_create自动处理存在/不存在逻辑) record, created = NumberRecord.objects.get_or_create( number=input_number, defaults={'info': f"针对数字{input_number}的专属信息"} ) serializer = NumberRecordSerializer(record) # 用状态码区分查询/新增结果 return Response(serializer.data, status=status.HTTP_200_OK if not created else status.HTTP_201_CREATED)
配置路由(urls.py)
from django.urls import path from .views import NumberHandlerAPI urlpatterns = [ path('api/handle-number/', NumberHandlerAPI.as_view(), name='handle-number'), ]
3. 后端基础配置
- 开发环境下,将
ALLOWED_HOSTS设为['*'],允许安卓客户端访问;生产环境需替换为具体域名/IP。 - 确保Django服务在可被安卓访问的网络环境下运行(比如本地测试时,手机和电脑连同一WiFi,用电脑IP访问)。
二、Kotlin Android前端实现
1. 添加网络依赖
在Module级别的build.gradle中引入Retrofit(安卓主流网络请求库):
dependencies { implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' }
2. 定义数据类与API接口
数据类(对应后端返回的JSON结构)
data class NumberRecord( val id: Int, val number: Int, val info: String, val created_at: String ) // 兼容错误返回的通用响应类 data class ApiResponse( val error: String? = null, val id: Int? = null, val number: Int? = null, val info: String? = null, val created_at: String? = null )
Retrofit API接口
import retrofit2.Call import retrofit2.http.Body import retrofit2.http.POST interface NumberApiService { @POST("api/handle-number/") fun handleNumber(@Body request: Map<String, Int>): Call<ApiResponse> }
3. 实现请求逻辑(以Activity为例)
import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import retrofit2.Call import retrofit2.Callback import retrofit2.Response import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory class MainActivity : AppCompatActivity() { private lateinit var apiService: NumberApiService override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化Retrofit,替换为你的Django服务地址(模拟器用10.0.2.2访问本地电脑) val retrofit = Retrofit.Builder() .baseUrl("http://192.168.1.100:8000/") // 示例IP,替换成实际地址 .addConverterFactory(GsonConverterFactory.create()) .build() apiService = retrofit.create(NumberApiService::class.java) val inputEt = findViewById<EditText>(R.id.input_number) val submitBtn = findViewById<Button>(R.id.submit_btn) val resultTv = findViewById<TextView>(R.id.result_tv) submitBtn.setOnClickListener { val inputStr = inputEt.text.toString().trim() // 输入校验 when { inputStr.isBlank() -> { resultTv.text = "请输入数字" return@setOnClickListener } inputStr.toIntOrNull() == null -> { resultTv.text = "请输入有效的整数" return@setOnClickListener } } val inputNumber = inputStr.toInt() // 构建请求体 val requestBody = mapOf("number" to inputNumber) // 发起异步请求 apiService.handleNumber(requestBody).enqueue(object : Callback<ApiResponse> { override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) { if (response.isSuccessful) { response.body()?.let { resp -> resp.error?.let { resultTv.text = "错误:$it" } ?: run { val status = if (response.code() == 201) "新增记录成功" else "查询到已有记录" resultTv.text = """ $status 数字:${resp.number} 信息:${resp.info} 创建时间:${resp.created_at} """.trimIndent() } } ?: run { resultTv.text = "返回数据为空" } } else { resultTv.text = "请求失败,状态码:${response.code()}" } } override fun onFailure(call: Call<ApiResponse>, t: Throwable) { resultTv.text = "网络错误:${t.message}" } }) } } }
4. 安卓配置项
- 在
AndroidManifest.xml添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
- 若使用Android 9+,需允许明文HTTP请求(开发环境):
- 在
res/xml目录创建network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">192.168.1.100</domain> <!-- 替换为你的Django服务地址 --> </domain-config> </network-security-config>- 在
AndroidManifest.xml的application标签添加:
android:networkSecurityConfig="@xml/network_security_config" - 在
三、测试与调试建议
- 先通过Postman/curl测试Django API,确保接口能正确处理请求并返回数据;
- 安卓模拟器访问本地Django服务时,用
10.0.2.2代替localhost; - 检查前后端字段名完全一致,避免序列化/反序列化失败;
- 开发阶段开启Django的调试模式,便于查看错误日志。
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

