Android动态Fragment中函数返回Null值问题求助
问题根源:Volley的异步执行特性
你遇到的问题核心在于Volley网络请求是异步执行的,代码执行顺序和你预想的完全不一样:
- 当你调用
masalariGetir(BOLUMID!!.toInt())时,函数会立刻创建请求并加入队列,然后直接返回空的responseObje集合。 - 此时网络请求还在后台跑,
Response.Listener里往集合加数据的逻辑,要等请求成功后才会执行。 - 所以你在
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
相关产品推荐
相关产品推荐

