Recyclerview 适配器内的 Volley 请求

Muh*_*zan 0 android kotlin android-studio android-volley android-recyclerview

我在 recyclerview 适配器中使用 Volley 图像请求。在快速滚动完成之前,请求似乎工作正常,每当我快速向上或向下滚动 recyclerview 时,应用程序崩溃并出现以下错误:

 java.lang.OutOfMemoryError: Could not allocate JNI Env: Failed anonymous mmap(0x0, 8192, 0x3, 0x22, -1, 0): Permission denied. See process maps in the log.
    at java.lang.Thread.nativeCreate(Native Method)
    at java.lang.Thread.start(Thread.java:883)
    at com.android.volley.RequestQueue.start(RequestQueue.java:134)
    at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:91)
    at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:67)
    at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:102)
    at com.squadtechs.hdwallpapercollection.main_activity.fragment.WallpaperAdapter.populateViews(WallpaperAdapter.kt:60)
    at com.squadtechs.hdwallpapercollection.main_activity.fragment.WallpaperAdapter.onBindViewHolder(WallpaperAdapter.kt:38)
    at com.squadtechs.hdwallpapercollection.main_activity.fragment.WallpaperAdapter.onBindViewHolder(WallpaperAdapter.kt:21)
Run Code Online (Sandbox Code Playgroud)

以下是我的onBindViewHolder()代码:

   override fun onBindViewHolder(holder: WallpaperHolder, position: Int) {
    populateViews(holder, position)
}

private fun populateViews(holder: WallpaperHolder, position: Int) {
    val requestQueue = Volley.newRequestQueue(context)
    val imageRequest = ImageRequest(
        list[position].wallpaper_image_url,
        Response.Listener { response ->
            holder.imgGrid.scaleType = ImageView.ScaleType.CENTER
            holder.imgGrid.setImageBitmap(response)
            holder.progress.visibility = View.GONE
        },
        1024,
        860,
        ImageView.ScaleType.CENTER,
        null,
        Response.ErrorListener { error ->
            Toast.makeText(context, "Error loading Image", Toast.LENGTH_LONG).show()
            holder.progress.visibility = View.GONE
        }).setRetryPolicy(
        DefaultRetryPolicy(
            20000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
        )
    )
    requestQueue.add(imageRequest)
    holder.txtCategory.visibility = View.GONE
}
Run Code Online (Sandbox Code Playgroud)

根据日志,在声明请求队列的行抛出错误,即 val requestQueue = Volley.newRequestQueue(context)

请记住:该应用程序在正常滚动时运行良好,但在快速滚动时崩溃

fjc*_*fjc 5

onBindViewHolder每次应该显示之前未绑定到视图(或未绑定)的元素时,您的回收器视图都会触发您的适配器。

当您快速滚动时,绑定和解除绑定会很快发生。每个bind都会产生一个HTTP请求,这是一个比较耗费内存的IO操作。

这是灾难的秘诀。不要根据这样的常规用户交互发送 HTTP 请求。如果有人不断上下滚动,则该应用程序肯定会耗尽内存。

相反,想想更好的策略。可能异步预加载数据,或者至少在加载后缓存数据。