在 Kotlin 中使用 Volley 内存不足

Out Of Memory using Volley in Kotlin

我正在 OutOfMemoryError 使用简单的 StringRequestKotlin 中的 Volley

令人惊讶的事实(至少对我而言)是我没有对大图像或大数据或类似的东西做任何事情。

因为我只是在测试,所以我使用 Volley 调用了 public 天气 API,我确定(在 Postman 中检查过)返回的只是一个简单的JSON.

我怎么可能得到OutOfMemoryError

为了实现 Volley 调用,我实现了一个 VolleySingleton 可能不正确,对此我不确定。我将 post 所有相关代码放在这里:

---> VolleySingleton.kt

object VolleySingleton : Application(){

    var requestQueue: RequestQueue? = null
        get() {
            if (requestQueue == null) {
                requestQueue = Volley.newRequestQueue(applicationContext)
            }
            return requestQueue
        }

    fun <T> addToRequestQueue(request: Request<T>) {
        requestQueue?.add(request)
    }
}

然后只是 MainActivity.kt 上使用 VolleySingleton.tk

的函数
 fun callWeatherAPI(){

          val request = StringRequest(Request.Method.GET,url,
                  Response.Listener { response ->
                      Log.d("API","RESPONSE: "+response)
                  },
                  Response.ErrorListener { error ->
                      Log.d("API","ERROR: "+error)
          })

            VolleySingleton.addToRequestQueue(request)
        }

你在做一件大事:

    var requestQueue: RequestQueue? = null
    get() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(applicationContext)
        }
        return requestQueue
    }

您在 getter 函数中使用 getter = Whosebug 在 getter/setter 中引用字段值,您应该使用 field 变量

    var requestQueue: RequestQueue? = null
    get() {
        if (field== null) {
            field= Volley.newRequestQueue(applicationContext)
        }
        return field
    }

from Kotlin documentation:

Classes in Kotlin cannot have fields. However, sometimes it is necessary to have a backing field when using custom accessors. For these purposes, Kotlin provides an automatic backing field which can be accessed using the field identifier:

这意味着您正在使用的字段(在 Kotlin 中称为 属性)始终引用 backing field 的 setter/getter,并且只能使用 [=12= 访问该支持字段]里面的变量getter/setter

这是对 的回复。 Kotlin 原生支持惰性初始化。

代替

var requestQueue: RequestQueue? = null
    get() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(applicationContext)
        }
        return requestQueue
    }

应该是

val requestQueue by lazy { Volley.newRequestQueue(applicationContext) }

这种方法允许更干净的代码,删除额外的空检查,确保线程安全(V-master 的回答不是线程安全的)并防止意外设置 requestQueue.

了解有关 lazy 的更多信息。