首页 > 解决方案 > Kotlin - 通过 Intent 将函数作为参数传递

问题描述

我在 kotlin 扩展文件中有这个函数来传递方法,但它不起作用。请解释一下它是如何正确制作的,我试试这个:

fun showErrorClientScreen(context: Context, action : () -> Unit) {
    val intent = Intent(context, RestClientErrorActivity::class.java)

    val bundle = Bundle()
    bundle.putSerializable(UPDATE_CLIENT_ERROR, ErrorClientListener {  action })
    intent.putExtra(UPDATE_CLIENT_ERROR_BUNDLE, bundle)

    context.startActivity(intent)
}

使用java接口

public interface ErrorClientListener extends Serializable {

    void tryAgainFunction();

}

以及我需要监听单击按钮并再次尝试发送请求的活动:

class RestClientErrorActivity: BaseActivity(), View.OnClickListener {

    private lateinit var errorClientListener: ErrorClientListener

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_rest_client_error)

        try {
            val bundle = intent.getBundleExtra(UPDATE_CLIENT_ERROR_BUNDLE)
            errorClientListener = bundle?.getSerializable(UPDATE_CLIENT_ERROR) as ErrorClientListener
        } catch (e: Exception) {
            e.message
        }
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.ib_update -> errorClientListener.tryAgainFunction()
        }
    }

}

标签: androidandroid-intentserializationkotlin

解决方案


活动之间打包比较奇怪,interfaces绝对不可取。Activity A它可能不在和之间序列化的一个原因Activity B是因为该对象是在 中创建的Activity A,它被视为匿名类创建并Activity A持有对该对象的引用,从而防止它被序列化。这很好,因为您可以在接口回调中创建对对象的引用,而这些对象的引用又将由实例化它的类持有。因此,垃圾收集器将无法对这些对象运行收集并释放空间;导致大量内存泄漏。

解决您的问题的替代方法可能是使用干净的体系结构和Singleton类模式,这两个活动都可以访问,并且只能通过 say 实例化一次Activity A

class SingletonErrorHandler private constructor(){
    var isError = false

    fun doOnError() {
        // do non view related stuff
        // like a network call or something          
    }

    companion object {
        val instance by lazy { SingletonErrorHandler() }
    }
}

在活动中您可以定义

class ActivityA : AppCompatActivity() {
    fun onError() {
        SingletonErrorHandler.instance.isError = true
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.a_activity)
    }
}

在活动 B

class ActivityB : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.b_activity)

        val errorHandler = SingletonErrorHandler.instance
        if(errorHandler.isError)
             errorHandler.doOnError()
    }
}

推荐阅读