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,实现异步结果的回调。
- 定义回调接口
interface RequestCallback { fun onSuccess(response: String) fun onError(error: String) }
- 修改
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) } }
- 在
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作为回调,无需额外定义接口。
- 修改
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) } }
- 在
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
相关产品推荐
相关产品推荐

