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

Fragment未关联上下文,ArrayAdapter与AsyncTask中requireContext()报错求助

问题分析与解决方案

错误原因

  1. 错误创建Fragment实例:你在onPostExecute里新建了LastSongs()实例,这个实例从未被添加到Activity中,既没有绑定View,也没有附着到上下文,完全不是当前显示的Fragment对象。
  2. 强引用导致的上下文失效:直接持有Fragment的强引用,当AsyncTask异步任务完成时,Fragment可能已经被销毁或与上下文分离,此时调用requireContext()必然抛出异常。

方案一:修复现有AsyncTask代码

使用弱引用持有Fragment,同时在更新UI前检查Fragment的状态,避免无效操作:

class GetSongListAsync(fragment: LastSongs) : AsyncTask<Void, Void, Array<String>>() {
    // 用弱引用持有Fragment,避免内存泄漏
    private val fragmentRef = WeakReference(fragment)

    override fun doInBackground(vararg params: Void): Array<String> {
        val url = URL("https://vivalaresistance.ru/radio/stuff/vlrradiobot.php?type=getPlaylist")
        val connection = url.openConnection() as HttpURLConnection
        connection.requestMethod = "GET"
        connection.connect()

        val songList = BufferedReader(InputStreamReader(connection.inputStream, "windows-1251"))

        connection.disconnect()
        return songList
            .readText()
            .replace("и&#774;", "й")
            .replace("И&#774;", "Й")
            .split("\n").dropLast(1).toTypedArray()
    }

    override fun onPostExecute(result: Array<String>) {
        super.onPostExecute(result)
        // 获取当前Fragment实例,若已回收则直接返回
        val fragment = fragmentRef.get() ?: return
        // 检查Fragment是否仍附着到Activity
        if (!fragment.isAdded) return
        
        // 使用当前Fragment的View获取ListView
        val list = fragment.view?.findViewById<ListView>(R.id.list) ?: return
        val arrayAdapter = ArrayAdapter(fragment.requireContext(), android.R.layout.simple_list_item_1, result)
        list.adapter = arrayAdapter
    }
}

方案二:改用Coroutines(推荐)

AsyncTask已被Android官方废弃,使用协程更符合现代开发规范,且能自动跟随Fragment生命周期:

class LastSongs : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 启动协程,自动在Fragment销毁时取消任务
        lifecycleScope.launch {
            // 在IO线程执行网络请求
            val songList = withContext(Dispatchers.IO) {
                val url = URL("https://vivalaresistance.ru/radio/stuff/vlrradiobot.php?type=getPlaylist")
                val connection = url.openConnection() as HttpURLConnection
                connection.requestMethod = "GET"
                connection.connect()

                val songList = BufferedReader(InputStreamReader(connection.inputStream, "windows-1251"))
                connection.disconnect()
                songList.readText()
                    .replace("и&#774;", "й")
                    .replace("И&#774;", "Й")
                    .split("\n").dropLast(1).toTypedArray()
            }
            // 回到主线程更新UI
            val list = view.findViewById<ListView>(R.id.list)
            val arrayAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, songList)
            list.adapter = arrayAdapter
        }
    }
}

内容的提问来源于stack exchange,提问作者Mikhail K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:03:07