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

Android动态Fragment中函数返回Null值问题求助

问题根源:Volley的异步执行特性

你遇到的问题核心在于Volley网络请求是异步执行的,代码执行顺序和你预想的完全不一样:

  1. 当你调用masalariGetir(BOLUMID!!.toInt())时,函数会立刻创建请求并加入队列,然后直接返回空的responseObje集合。
  2. 此时网络请求还在后台跑,Response.Listener里往集合加数据的逻辑,要等请求成功后才会执行。
  3. 所以你在onCreate里打印masalar的时候,数据根本还没被添加进去,自然是空集合。
解决方案:用回调函数处理异步结果

我们不能让masalariGetir直接返回集合,而是要通过回调接口在请求完成后获取数据。具体实现步骤如下:

1. 定义回调接口

在你的Fragment中(或者单独文件)定义一个接口,用来传递请求成功/失败的结果:

interface MasaBilgileriCallback {
    fun onSuccess(masalar: ArrayList<MasaBilgileri>)
    fun onError(errorMessage: String?)
}

2. 修改masalariGetir方法

把返回值改成Unit,并接收回调作为参数,在请求完成后通过回调传递数据:

fun masalariGetir(BOLUMID: Int, callback: MasaBilgileriCallback) {
    val json = JSONObject()
    json.put("BOLUMID", BOLUMID)
    val jsonArray = JSONArray().put(json)
    
    val jsonArrayRequest = JsonArrayRequest(
        Request.Method.POST,
        "http://${IPADRES}/restoway/rwservice/masa",
        jsonArray,
        Response.Listener { response ->
            val responseObje = ArrayList<MasaBilgileri>()
            for (satir in 0..response.length() - 1) {
                val gecici = MasaBilgileri(
                    response.getJSONObject(satir).getInt("ID"),
                    response.getJSONObject(satir).getInt("BOLUMID"),
                    response.getJSONObject(satir).getString("BOLUMADI"),
                    response.getJSONObject(satir).getInt("MASANO"),
                    response.getJSONObject(satir).getString("MASAADI")
                )
                responseObje.add(gecici)
            }
            // 请求成功,通过回调返回填充好的数据
            callback.onSuccess(responseObje)
        },
        Response.ErrorListener { error ->
            Log.e("ERROR", error.message)
            // 请求失败,传递错误信息
            callback.onError(error.message)
        }
    )
    Singleton.getInstance(requireContext()).addToRequestQueue(jsonArrayRequest)
}

3. 在onCreate中调用并处理结果

现在调用masalariGetir时,传入回调实现,在onSuccess里就能拿到正确的数据了:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    IPADRES = arguments?.getString("IPADRES")
    BOLUMID = arguments?.getInt("BOLUMID")
    
    BOLUMID?.let { bolumId ->
        masalariGetir(bolumId, object : MasaBilgileriCallback {
            override fun onSuccess(masalar: ArrayList<MasaBilgileri>) {
                Log.e("MASALAR", masalar.toString()) // 这里就能拿到非空数据了!
                // 在这里可以初始化适配器、更新UI等操作
                adapter = MasaListesiAdapter(masalar)
            }

            override fun onError(errorMessage: String?) {
                // 处理错误,比如显示Toast或者错误提示
            }
        })
    }
}
额外注意事项
  • 预防内存泄漏:如果Fragment可能被销毁,建议用WeakReference包裹回调,或者在Fragment销毁时取消Volley请求:
    private var request: Request<*>? = null
    
    // 在masalariGetir里保存请求引用
    request = jsonArrayRequest
    Singleton.getInstance(requireContext()).addToRequestQueue(request)
    
    // 在Fragment销毁时取消请求
    override fun onDestroy() {
        super.onDestroy()
        request?.let { Singleton.getInstance(requireContext()).cancelRequest(it) }
    }
    
  • UI操作安全:Volley的回调默认在主线程执行,所以你可以直接在onSuccess里更新UI(比如设置RecyclerView适配器),不需要额外切换线程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:27:44