WeakReference无法在Kotlin中工作

时间:2016-05-04 23:34:32

标签: android kotlin

我正在Kotlin中实现AsyncTask,我需要WeakReference来执行onPostExecute()方法中运行的回调。我在调用execute()之前设置了侦听器引用,但在调用onPostExecute()后,WeakReference的值为null

class PhotoRotationTask(uri: Uri, filePath: String, resolver: ContentResolver) : AsyncTask<Int, Int, Int>() {
    private var weakRef : WeakReference<OnBitmapProcessedListener>? = null

    var sourceUri : Uri
    var resolver : ContentResolver
    var destPath: String

    init {
        this.sourceUri = uri
        this.resolver = resolver
        this.destPath = filePath
    }

    fun setOnBitmapProcessedListener(listener: OnBitmapProcessedListener){
        weakRef = WeakReference(listener)
        Log.d("RotationTask", "set listener ${weakRef?.get() != null}") //This Log proves that weakRef is initialized before onPostExecute()
    }

    override fun doInBackground(vararg params: Int?): Int? {
        //Bitmap processing, weakRef is never called in this function
    }

    override fun onPostExecute(result: Int?) {
        Log.d("RotationTask", "result: $result") //This log proves that onPostExecute() is called eventually
        weakRef!!.get()?.onBitmapProcessed() //This implies that weakRef is not null, because app never crashes, but onBitmapProcessed is not called, so the reference is gone.
    }

}

listener变量修改了我的活动的UI,因此它包含对我的活动的引用。永远不会重新创建活动,我的手机在AsyncTask启动后仍然不会旋转或触摸。如何清除WeakReference

2 个答案:

答案 0 :(得分:7)

问题出在您listener传递的WeakReference和本地变量中。

WeakReferenceknown not to keep an object from being garbage collected,因此如果没有其他可访问的强引用,则一旦通过本地变量引用它的方法完成,它就可以随时回收。这正是你的情况下发生的事情,因为弱引用变为null

解决方案是将强引用存储到在调用代码中某处作为listener传递的对象(因为它使用活动,活动本身可以将其存储在属性,以便listener的生命周期与活动的生命周期相匹配。)

例如,声明属性

lateinit var currentListener: OnBitmapProcessedListener

在活动代码中,然后存储您在该属性中创建的listener

val task = PhotoRotationTask(uri, filePath, resolver)

task.setOnBitmapProcessedListener(object : OnBitmapProcessedListener {
         // here goes the implementation
     }.apply { currentListener = this } // note this line
)

如果可以使用多个任务和监听器,那么请注意存储所有监听器。

答案 1 :(得分:1)

您需要在其他位置保留对OnBitmapProcessedListener的强引用,以确保GC不会清除WeakReference。