You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin lateinit变量未初始化报错,如何修正JSON数据获取后的变量更新?

问题根源分析

你遇到的kotlin.UninitializedPropertyAccessException本质是异步操作的时序问题:

fetchJson里使用OkHttp的enqueue()发起的是异步网络请求——这个请求会在后台线程执行,而你的fetchJson函数会立刻返回name2,这时候name2还没被onResponse里的代码初始化,自然就抛出异常了。lateinit只是告诉编译器"我会在使用前初始化",但异步场景下你没法保证这一点。

解决方案:用Kotlin协程(推荐)

现在Android开发中最简洁的异步处理方式是Kotlin协程,它能让异步代码看起来像同步代码,完美解决这个时序问题:

步骤1:修改fetchJson为挂起函数

我们用OkHttp的await()扩展函数(需要依赖kotlinx-coroutines-okhttp)来同步等待网络响应,确保拿到数据后再返回:

// 添加suspend标记,将函数转为挂起函数
suspend fun fetchJson(): Array<Articles>? {
    println("Attempting to fetch JSON")
    val url1 = "https://go-api-api.herokuapp.com/"
    val request = Request.Builder().url(url1).build()
    val client = OkHttpClient()

    return try {
        // await()会挂起协程,直到网络请求完成返回响应
        val response = client.newCall(request).await()
        val body = response.body()?.string() ?: return null
        println(body)
        
        val gson = GsonBuilder().create()
        gson.fromJson(body, Array<Articles>::class.java)
    } catch (e: IOException) {
        println("Failed to execute request: ${e.message}")
        null
    } catch (e: Exception) {
        println("Error parsing JSON: ${e.message}")
        null
    }
}

步骤2:在Fragment中用生命周期协程调用

Fragment可以使用viewLifecycleOwner.lifecycleScope来启动协程,它会自动和Fragment的视图生命周期绑定,避免内存泄漏:

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    super.onCreateView(inflater, container, savedInstanceState)
    val view1 = inflater?.inflate(R.layout.fragment_home, container, false) ?: return null
    val recyclerview = view1.findViewById<RecyclerView>(R.id.recycler_view)
    recyclerview.layoutManager = LinearLayoutManager(activity)

    // 启动协程获取数据,拿到数据后再设置适配器
    viewLifecycleOwner.lifecycleScope.launch {
        val articles = fetchJson()
        articles?.let {
            recyclerview.adapter = CustomAdaptor(it)
        }
    }

    return view1
}
备选方案:使用回调接口

如果暂时不想用协程,也可以通过回调接口来确保数据获取完成后再更新UI:

步骤1:定义回调接口

interface JsonFetchCallback {
    fun onSuccess(articles: Array<Articles>)
    fun onFailure(errorMsg: String)
}

步骤2:修改fetchJson接受回调

fun fetchJson(callback: JsonFetchCallback) {
    println("Attempting to fetch JSON")
    val url1 = "https://go-api-api.herokuapp.com/"
    val request = Request.Builder().url(url1).build()
    val client = OkHttpClient()

    client.newCall(request).enqueue(object : Callback {
        override fun onResponse(call: Call?, response: Response?) {
            val body = response?.body()?.string()
            println(body)
            val gson = GsonBuilder().create()
            try {
                val articles = gson.fromJson(body, Array<Articles>::class.java)
                callback.onSuccess(articles)
            } catch (e: Exception) {
                callback.onFailure("JSON解析错误: ${e.message}")
            }
        }

        override fun onFailure(call: Call?, e: IOException?) {
            callback.onFailure("请求失败: ${e?.message}")
        }
    })
}

步骤3:在Fragment中调用并更新UI

注意:OkHttp的回调在后台线程,更新UI必须切回主线程:

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    super.onCreateView(inflater, container, savedInstanceState)
    val view1 = inflater?.inflate(R.layout.fragment_home, container, false) ?: return null
    val recyclerview = view1.findViewById<RecyclerView>(R.id.recycler_view)
    recyclerview.layoutManager = LinearLayoutManager(activity)

    fetchJson(object : JsonFetchCallback {
        override fun onSuccess(articles: Array<Articles>) {
            // 切回主线程更新RecyclerView
            requireActivity().runOnUiThread {
                recyclerview.adapter = CustomAdaptor(articles)
            }
        }

        override fun onFailure(errorMsg: String) {
            println(errorMsg)
        }
    })

    return view1
}
关键总结

不管用哪种方案,核心都是确保在网络请求完成、数据解析完成后,再去初始化RecyclerView的适配器——不能在异步操作还没完成时就返回未初始化的变量。协程方案更简洁易读,是当前Android开发的首选方式。

内容的提问来源于stack exchange,提问作者subhra jyoti das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:28:25