[职业竞赛][移动应用]网络请求、JSON 文件读取解析、APP全局变量
网络请求、JSON 文件读取解析
例子代码
// 1. 网络请求 - 用户登录获取token/*** 登录请求数据类(确保JSON格式规范)* @property username 用户名* @property password 密码*/
data class LoginRequest(val username: String, val password: String)/*** 登录响应数据类* @property token 认证令牌*/
data class LoginResponse(val token: String)/*** 认证服务接口*/
interface AuthService {/*** 用户登录接口* @param request 登录请求体(JSON格式)* @return 登录响应(JSON格式)*/@POST("auth/login")@Headers("Content-Type: application/json") // 明确指定请求体为JSONsuspend fun login(@Body request: LoginRequest): LoginResponse
}// 2. Retrofit客户端单例
object RetrofitClient {// 延迟初始化的Retrofit实例private lateinit var retrofit: Retrofit/*** 初始化Retrofit客户端* @param baseUrl API基础地址*/fun initialize(baseUrl: String) {retrofit = Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()) // JSON转换器.build()}// 认证服务实例val authService: AuthService by lazy {retrofit.create(AuthService::class.java)}// 用户服务实例val userService: UserService by lazy {retrofit.create(UserService::class.java)}
}// 3. 用户数据服务接口
/*** 用户服务接口*/
interface UserService {/*** 获取用户数据* @param token 认证令牌* @return 用户数据(JSON格式)*/@GET("user/data")suspend fun getUserData(@Header("Authorization") token: String): UserData
}/*** 用户数据响应类* @property id 用户ID* @property name 用户名*/
data class UserData(val id: Int, val name: String)// 4. 登录功能封装
/*** 用户登录函数* @param username 用户名* @param password 密码* @return 认证令牌(失败返回null)*/
suspend fun loginUser(username: String, password: String): String? {return try {// 创建登录请求对象(自动转换为JSON)val request = LoginRequest(username, password)val response = RetrofitClient.authService.login(request)response.token} catch (e: Exception) {// 捕获网络异常和JSON解析异常null}
}/*** 获取用户数据* @param token 认证令牌* @return 用户数据对象(失败返回null)*/
suspend fun fetchUserData(token: String): UserData? {return try {// 添加Bearer认证前缀RetrofitClient.userService.getUserData("Bearer $token")} catch (e: Exception) {null}
}// 5. 配置文件读取
/*** 应用配置数据类* @property apiUrl API基础地址* @property enableFeature 功能开关*/
data class AppConfig(val apiUrl: String, val enableFeature: Boolean)/*** 从assets读取配置文件* @param context 上下文对象* @return 配置对象(失败返回null)*/
fun readConfig(context: Context): AppConfig? {return try {context.assets.open("config.json").use { inputStream ->val json = inputStream.bufferedReader().use { it.readText() }Gson().fromJson(json, AppConfig::class.java)}} catch (e: Exception) {null}
}// 6. Activity使用示例
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 读取配置文件val config = readConfig(this) ?: run {Toast.makeText(this, "配置加载失败", Toast.LENGTH_SHORT).show()return}// 初始化Retrofit(使用配置中的API地址)RetrofitClient.initialize(config.apiUrl)// 登录按钮点击事件loginButton.setOnClickListener {lifecycleScope.launch {// 执行登录val token = loginUser("user", "pass")token?.let { validToken ->// 获取用户数据val userData = fetchUserData(validToken)userData?.let {// 主线程更新UIwithContext(Dispatchers.Main) {nameTextView.text = it.name}} ?: showError("用户数据获取失败")} ?: showError("登录失败")}}}private fun showError(msg: String) {runOnUiThread { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() }}
}
依赖项(build.gradle)
dependencies {implementation 'com.squareup.retrofit2:retrofit:2.9.0'implementation 'com.squareup.retrofit2:converter-gson:2.9.0'implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
}
权限(AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET"/>
APP全局变量
创建自定义 Application 类
// MyApp.kt
import android.app.Applicationclass MyApp : Application() {// 全局变量示例var globalUserId: String = ""var isLoggedIn: Boolean = falsecompanion object {// 快速访问实例的静态方法@JvmStaticfun getInstance(): MyApp = instance as MyAppprivate lateinit var instance: MyApp}override fun onCreate() {super.onCreate()instance = this}
}
在 AndroidManifest.xml 中注册
<applicationandroid:name=".MyApp" <!-- 关键:指定自定义 Application -->android:icon="@mipmap/ic_launcher"android:label="@string/app_name"... ><activity android:name=".MainActivity">...</activity>
</application>
在 Activity 中使用全局变量
// MainActivity.kt
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 设置全局变量MyApp.getInstance().globalUserId = "user123"MyApp.getInstance().isLoggedIn = true// 读取全局变量val userId = MyApp.getInstance().globalUserIdval loginStatus = MyApp.getInstance().isLoggedInToast.makeText(this, "User ID: $userId", Toast.LENGTH_SHORT).show()}
}
在其他组件中使用(如 Fragment)
class MyFragment : Fragment() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {// 访问全局变量val app = (requireActivity().application as MyApp)if (app.isLoggedIn) {// 执行登录用户的操作}}
}
关键点说明
-
自定义 Application 类:
- 继承
Application
类 - 使用
companion object
提供静态访问点 - 在
onCreate()
中初始化实例
- 继承
-
线程安全:
- 简单示例未加锁,实际生产环境需考虑同步问题
- 建议对可变全局变量使用
@Volatile
或同步块
-
使用场景:
- 适合存储应用级状态(如用户会话、全局配置)
- 不适合存储大数据(考虑使用 ViewModel 或持久化存储)
-
生命周期:
- Application 实例在应用启动时创建
- 会持续存在于整个应用生命周期