【问题标题】:Out Of Memory using Volley in Kotlin在 Kotlin 中使用 Volley 内存不足
【发布时间】:2017-10-13 06:12:42
【问题描述】:

我在Kotlin 中使用简单的StringRequestVolley 得到OutOfMemoryError

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

因为我只是在测试,所以我使用 Volley 调用了一个公共天气 API,我确信(在 Postman 中查看)它只返回一个简单的 JSON。

我怎么可能得到OutOfMemoryError

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

---> 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)
        }

【问题讨论】:

    标签: out-of-memory kotlin android-volley


    【解决方案1】:

    这是对V-master's answer的回复。 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的信息。

    【讨论】:

    • 真的。我的回答是关于哪里出了问题,而不是关于应该如何做。
    • @Joshua 我正在以您提到的方式使用lazy,并且如问题中所述,OutOfMemoryError 正在发生。知道发生了什么吗?
    【解决方案2】:

    你正在做一件大事:

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

    您在 getter function = stackoverflow 中使用 getter 在 getter/setter 中引用字段值,您应该使用 field 变量

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

    from Kotlin documentation:

    Kotlin 中的类不能有字段。但是,有时在使用自定义访问器时需要有一个支持字段。为此,Kotlin 提供了一个自动支持字段,可以使用 field 标识符访问该字段:

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

    【讨论】:

    • 嗯,我明白了,谢谢,您介意详细解释一下吗?我有两个主要问题,1-如果我使用field,我如何将fieldrequestQueue 链接起来,以及2-为什么使用requestQueue 会产生溢出?谢谢!!
    • requestQueue 是对字段的 setter/getter 的引用,在 Kotlin 中无法直接访问字段,这就是为什么他们添加了 field 变量,它是对字段的直接引用和仅在 getter/setter kotlinlang.org/docs/reference/properties.html#backing-fields 内部可见
    • AndroidStudio 在您编写原始代码时,在 getter 的左侧显示递归图标 - 此指示器可以帮助您通过 stackoverflow/outOfMemory 找到此类错误
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    相关资源
    最近更新 更多