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

Android Kotlin:API调用后fetchedTags为空,如何获取异步数据?

问题分析

你的问题核心在于API调用是异步操作——fetchTags()执行时,它不会阻塞主线程等待接口返回数据,而是立刻继续执行后面的println(fetchedTags[0].name),这时候接口请求还在后台跑,fetchedTags自然还是null,直接访问甚至会抛出空指针异常。

解决方案

下面给你几种适合Kotlin/Android的常见解决方式,按推荐程度排序:

1. 使用Kotlin协程(最推荐)

Kotlin协程让异步代码写起来像同步代码,非常简洁。你需要做这些修改:

  • 给fetchTags()加上suspend关键字,让它成为挂起函数
  • 在onCreate里用lifecycleScope.launch启动协程,确保在Activity生命周期内执行

修改后的代码示例:

class MainActivity : AppCompatActivity() {
    var fetchedTags: List<Tags>? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 用lifecycleScope启动协程,绑定Activity生命周期
        lifecycleScope.launch {
            fetchTags()
            // 现在API请求已经完成,fetchedTags有数据了
            fetchedTags?.let {
                println(it[0].name)
                fetchBooks()
                makeMapOutOfTagsAndBooks()
            } ?: run {
                // 处理接口请求失败的情况
                println("Failed to fetch tags")
            }
        }
    }

    // 标记为挂起函数,内部用withContext切换到IO线程执行网络请求
    private suspend fun fetchTags() {
        withContext(Dispatchers.IO) {
            // 这里写你的网络请求逻辑,比如用Retrofit或者OkHttp
            // 假设请求成功后给fetchedTags赋值
            fetchedTags = apiService.getTags()
        }
    }
}

2. 使用回调函数

如果暂时不想用协程,可以给fetchTags()加一个回调参数,当接口请求完成后触发回调:

class MainActivity : AppCompatActivity() {
    var fetchedTags: List<Tags>? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        fetchTags { tags ->
            fetchedTags = tags
            // 在回调里执行后续操作
            println(tags[0].name)
            fetchBooks()
            makeMapOutOfTagsAndBooks()
        }
    }

    fun fetchTags(onSuccess: (List<Tags>) -> Unit) {
        // 这里写你的异步网络请求逻辑
        // 比如用OkHttp的Callback:
        val request = Request.Builder().url("your-api-url").build()
        OkHttpClient().newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                // 处理请求失败
            }

            override fun onResponse(call: Call, response: Response) {
                response.body?.let {
                    // 解析返回的JSON为List<Tags>
                    val tags = Gson().fromJson(it.string(), object : TypeToken<List<Tags>>() {}.type)
                    // 切换回主线程更新UI或执行后续操作
                    runOnUiThread {
                        onSuccess(tags)
                    }
                }
            }
        })
    }
}

3. 使用LiveData(适合MVVM架构)

如果你用MVVM模式,可以把fetchedTags改成LiveData,观察它的变化来执行后续操作:

class MainActivity : AppCompatActivity() {
    // 用MutableLiveData存储标签数据
    private val fetchedTags = MutableLiveData<List<Tags>>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        fetchTags()
        // 观察LiveData的变化
        fetchedTags.observe(this) { tags ->
            tags?.let {
                println(it[0].name)
                fetchBooks()
                makeMapOutOfTagsAndBooks()
            }
        }
    }

    fun fetchTags() {
        // 异步请求接口,成功后更新LiveData
        OkHttpClient().newCall(Request.Builder().url("your-api-url").build()).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                // 处理失败
            }

            override fun onResponse(call: Call, response: Response) {
                response.body?.let {
                    val tags = Gson().fromJson(it.string(), object : TypeToken<List<Tags>>() {}.type)
                    runOnUiThread {
                        fetchedTags.value = tags
                    }
                }
            }
        })
    }
}
关键注意点
  • 永远不要在主线程执行网络请求,Android会抛出NetworkOnMainThreadException,所以异步请求必须在后台线程执行,完成后切回主线程处理结果
  • 处理fetchedTags为null的情况,避免空指针异常(比如用?.let或者空合并运算符)

内容的提问来源于stack exchange,提问作者Zim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:04:07