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

Android Kotlin:如何在独立类中回调Activity内的方法?

问题描述

我创建了HttpRequests.kt类,用Volley实现了简单的网络请求方法:

import android.content.Context
import android.util.Log
import com.android.volley.Request
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley

class HttpRequests() {

    fun doARequest(context: Context){
        val queue = Volley.newRequestQueue(context)
        val url = "https://www.google.com"

        val stringRequest = StringRequest(
            Request.Method.GET, url,
            { response ->
                // 如何在这里调用ConfigActivity里的方法,并传入response变量?
            },
            { error -> Log.d("http","[ERROR]: $error") })

        queue.add(stringRequest)
    }

}

这个doARequest方法会在ConfigActivity的onCreate中调用:

class ConfigActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // 处理请求
        val requests: HttpRequests = HttpRequests()
        requests.doARequest(this)
    }
}

因为Volley的响应是异步的,现在需要在StringRequest的响应回调里调用ConfigActivity已有的方法(比如请求成功后跳转页面),该怎么实现?

解决方案

方法1:接口回调(推荐,解耦性强)

通过定义回调接口,让ConfigActivity实现接口后传递给HttpRequests,实现异步结果的回调。

  1. 定义回调接口
interface RequestCallback {
    fun onSuccess(response: String)
    fun onError(error: String)
}
  1. 修改HttpRequests的方法,新增回调参数
class HttpRequests() {

    fun doARequest(context: Context, callback: RequestCallback){
        val queue = Volley.newRequestQueue(context)
        val url = "https://www.google.com"

        val stringRequest = StringRequest(
            Request.Method.GET, url,
            { response ->
                callback.onSuccess(response)
            },
            { error -> 
                Log.d("http","[ERROR]: $error")
                callback.onError(error.toString())
            })

        queue.add(stringRequest)
    }

}
  1. 在ConfigActivity中实现接口并调用自身方法
class ConfigActivity : AppCompatActivity(), RequestCallback {
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // 处理请求
        val requests: HttpRequests = HttpRequests()
        requests.doARequest(this, this)
    }

    // 实现回调方法
    override fun onSuccess(response: String) {
        // 这里调用你需要的方法,比如跳转页面
        navigateToNextPage()
    }

    override fun onError(error: String) {
        // 处理错误逻辑,比如弹出提示
    }

    // 你自己的业务方法,示例:跳转页面
    private fun navigateToNextPage() {
        startActivity(Intent(this, NextActivity::class.java))
    }
}

方法2:Lambda表达式(更简洁)

直接在调用doARequest时传入Lambda作为回调,无需额外定义接口。

  1. 修改HttpRequests的方法参数
class HttpRequests() {

    fun doARequest(
        context: Context, 
        onSuccess: (String) -> Unit, 
        onError: (String) -> Unit
    ){
        val queue = Volley.newRequestQueue(context)
        val url = "https://www.google.com"

        val stringRequest = StringRequest(
            Request.Method.GET, url,
            { response ->
                onSuccess(response)
            },
            { error -> 
                Log.d("http","[ERROR]: $error")
                onError(error.toString())
            })

        queue.add(stringRequest)
    }

}
  1. 在ConfigActivity中调用
class ConfigActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // 处理请求
        val requests: HttpRequests = HttpRequests()
        requests.doARequest(
            this,
            onSuccess = { response ->
                // 调用自身业务方法
                navigateToNextPage()
            },
            onError = { error ->
                // 处理错误逻辑
            }
        )
    }

    private fun navigateToNextPage() {
        startActivity(Intent(this, NextActivity::class.java))
    }
}

关键注意事项

不管用哪种方法,都要警惕内存泄漏:如果Activity已销毁但请求仍在进行,回调持有Activity引用会导致内存泄漏。可以通过两种方式规避:

  • 用WeakReference包装回调或Context:
class HttpRequests() {
    fun doARequest(context: Context, callback: RequestCallback){
        val weakCallback = WeakReference(callback)
        val queue = Volley.newRequestQueue(context)
        val stringRequest = StringRequest(
            Request.Method.GET, url,
            { response ->
                weakCallback.get()?.onSuccess(response)
            },
            { error -> 
                Log.d("http","[ERROR]: $error")
                weakCallback.get()?.onError(error.toString())
            })
        queue.add(stringRequest)
    }
}
  • 在Activity销毁时取消Volley请求:
private var stringRequest: StringRequest? = null
private var requestQueue: RequestQueue? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    requestQueue = Volley.newRequestQueue(this)
    stringRequest = StringRequest(...)
    requestQueue?.add(stringRequest)
}

override fun onDestroy() {
    super.onDestroy()
    stringRequest?.cancel()
    requestQueue?.cancelAll { true }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:42:44