首页 > 解决方案 > 通过位图解码提高 BaseAdapter 的性能

问题描述

我正在尝试开发一个应用程序,用户可以在其中拍照并将其保存在图库中。该图像的路径作为字符串保存在数据库中。我有一个使用 Adapter 并显示图像的 GridView(通过使用 Bitmap.decodeFile 和 BitMap.Options 对其进行解码以将其与 ImageView 大小匹配)。

问题是,适配器的这种解码需要很长时间,我的 UI 会出现延迟,“严重”延迟大约 3 秒。我需要一些帮助来优化它。

我在 Kotlin 中执行此操作,我的 OptimiseImage 类如下(后面是 Adapter 类中的 getView 方法):

    class OptimiseImage {
    companion object {
        fun getBitmap (iView: ImageView, imagePath: String):Bitmap {
            // Get the dimensions of the View
            val targetW = iView.getWidth()
            val targetH = iView.getHeight()

            // Get the dimensions of the bitmap
            val bmOptions = BitmapFactory.Options() // Returns Option Object
            bmOptions.inJustDecodeBounds = true // So it does not run out of memory if image is big
            BitmapFactory.decodeFile(imagePath, bmOptions) // But can still query the size of the image
            val photoW = bmOptions.outWidth
            val photoH = bmOptions.outHeight

            // Determine how much to scale down the image
            // Return the lowest out of the two based on photo orientation
            val scaleFactor = Math.min(photoW / targetW, photoH / targetH)

            // Decode the image file into a Bitmap sized to fill the View
            bmOptions.inJustDecodeBounds = false
            bmOptions.inSampleSize = scaleFactor

            return BitmapFactory.decodeFile(imagePath, bmOptions)
        }

        fun getBitmap(height:Int, width:Int, imagePath: String):Bitmap {
            // Get the dimensions of the View
            val targetW = width
            val targetH = height

            // Get the dimensions of the bitmap
            val bmOptions = BitmapFactory.Options() // Returns Option Object
            bmOptions.inJustDecodeBounds = true // So it does not run out of memory if image is big
            BitmapFactory.decodeFile(imagePath, bmOptions) // But can still query the size of the image
            val photoW = bmOptions.outWidth
            val photoH = bmOptions.outHeight

            // Determine how much to scale down the image
            // Return the lowest out of the two based on photo orientation
            val scaleFactor = Math.min(photoW / targetW, photoH / targetH)

            // Decode the image file into a Bitmap sized to fill the View
            bmOptions.inJustDecodeBounds = false
            bmOptions.inSampleSize = scaleFactor

            return BitmapFactory.decodeFile(imagePath, bmOptions)
        }
    }
}

我的任何 getView 方法如下:

   override fun getView(i: Int, convertView: View?, viewGroup: ViewGroup): View {
    Log.d(TAG,"In getView")
    var cView = convertView
    val (_, name, company, _, imagePath) = mSitesData[i]

    if (convertView == null) {
        val layoutInflater = LayoutInflater.from(context)
        cView = layoutInflater.inflate(R.layout.sites_grid_layout, null)
    }
    val iView = cView!!.findViewById(R.id.imageview_cover_art) as ImageView
    val siteName = cView.findViewById(R.id.site_name) as TextView
    val siteCompany = cView.findViewById(R.id.company_name) as TextView

    if (imagePath.equals("")){
        iView.setImageResource(R.drawable.camera_item)
    } else {
        val image = OptimiseImage.getBitmap(165,165,imagePath) //How to avoid this slowing down the UI?
        iView.setImageBitmap(image)
    }
    Log.d(TAG,"Out of GetView")
    siteName.text = name
    siteCompany.text = company
    return cView
}

标签: androidperformancegridviewbaseadapter

解决方案


推荐阅读