Android Coil ImageLoader MemoryCache设置Key与复用内存缓存,Kotlin
- import android.content.ContentUris
- import android.content.Context
- import android.net.Uri
- import android.os.Bundle
- import android.provider.MediaStore
- import android.util.Log
- import androidx.appcompat.app.AppCompatActivity
- import androidx.lifecycle.lifecycleScope
- import androidx.recyclerview.widget.GridLayoutManager
- import androidx.recyclerview.widget.LinearLayoutManager
- import androidx.recyclerview.widget.RecyclerView
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.launch
- class MainActivity : AppCompatActivity() {
- companion object {
- const val TAG = "fly"
- const val SPAN_COUNT = 8
- }
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.rv_layout)
- val rv = findViewById<RecyclerView>(R.id.rv)
- val layoutManager = GridLayoutManager(this, SPAN_COUNT)
- layoutManager.orientation = LinearLayoutManager.VERTICAL
- val adapter = ImageAdapter(this, 0)
- rv.adapter = adapter
- rv.layoutManager = layoutManager
- //rv.setHasFixedSize(true)
- //rv.setItemViewCacheSize(SPAN_COUNT * 20)
- //rv.recycledViewPool.setMaxRecycledViews(0, SPAN_COUNT * 20)
- val ctx = this
- lifecycleScope.launch(Dispatchers.IO) {
- val lists = readAllImage(ctx)
- Log.d(TAG, "readAllImage size=${lists.size}")
- lifecycleScope.launch(Dispatchers.Main) {
- adapter.dataChanged(lists)
- }
- }
- }
- class MyData(var path: String, var uri: Uri)
- private fun readAllImage(ctx: Context): ArrayList<MyData> {
- val photos = ArrayList<MyData>()
- //读取所有图
- val cursor = ctx.contentResolver.query(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null
- )
- while (cursor!!.moveToNext()) {
- //路径
- val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
- val id = cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)
- val imageUri: Uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getLong(id))
- //名称
- //val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
- //大小
- //val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))
- photos.add(MyData(path, imageUri))
- }
- cursor.close()
- return photos
- }
- }
复制代码
- import android.content.Context
- import android.graphics.Bitmap
- import android.util.Log
- import android.view.View
- import android.view.ViewGroup
- import androidx.appcompat.widget.AppCompatImageView
- import androidx.lifecycle.lifecycleScope
- import androidx.recyclerview.widget.RecyclerView
- import coil.ImageLoader
- import coil.memory.MemoryCache
- import coil.request.CachePolicy
- import coil.request.ImageRequest
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.launch
- class ImageAdapter : RecyclerView.Adapter<ImageHolder> {
- private var mCtx: Context? = null
- private var mImageLoader: ImageLoader? = null
- private var mViewSize = 0
- constructor(ctx: Context, type: Int) : super() {
- mCtx = ctx
- mImageLoader = ImageLoader.Builder(mCtx!!)
- .memoryCachePolicy(CachePolicy.ENABLED)
- .availableMemoryPercentage(0.9999)
- .bitmapPoolingEnabled(true)
- .bitmapConfig(Bitmap.Config.RGB_565)
- .diskCachePolicy(CachePolicy.ENABLED)
- .build()
- Log.d(MainActivity.TAG, "memoryCache.maxSize=${mImageLoader?.memoryCache?.maxSize}")
- mViewSize = mCtx!!.resources.displayMetrics.widthPixels / MainActivity.SPAN_COUNT
- }
- private var mItems = ArrayList<MainActivity.MyData>()
- fun dataChanged(items: ArrayList<MainActivity.MyData>) {
- this.mItems = items
- notifyDataSetChanged()
- }
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageHolder {
- val view = MyIV(mCtx!!, mViewSize)
- return ImageHolder(view)
- }
- override fun getItemCount(): Int {
- return mItems.size
- }
- override fun onBindViewHolder(holder: ImageHolder, position: Int) {
- bind(mItems[position], holder.image)
- }
- private fun bind(data: MainActivity.MyData, image: MyIV) {
- val key = MemoryCache.Key.invoke(data.path)
- val bmp = mImageLoader?.memoryCache?.get(key)
- if (bmp != null && bmp.byteCount > 0) {
- Log.d(
- MainActivity.TAG,
- "memory cache bmp=${bmp.byteCount} ${mImageLoader?.memoryCache?.size}/${mImageLoader?.memoryCache?.maxSize}"
- )
- image.setImageBitmap(bmp)
- } else {
- val t = System.currentTimeMillis()
- val request = ImageRequest.Builder(mCtx!!)
- .data(data.uri)
- .size(mViewSize)
- .target(image)
- .memoryCacheKey(key)
- .build()
- (mCtx as? MainActivity)?.lifecycleScope?.launch(Dispatchers.IO) {
- mImageLoader?.execute(request)
- }
- Log.d(MainActivity.TAG, "no memory cache time=${System.currentTimeMillis() - t}")
- }
- }
- }
- class ImageHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- var image = itemView as MyIV
- }
- class MyIV : AppCompatImageView {
- private var mSize = 0
- constructor(ctx: Context, size: Int) : super(ctx) {
- mSize = size
- scaleType = ScaleType.CENTER_CROP
- }
- override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec)
- setMeasuredDimension(mSize, mSize)
- }
- }
复制代码
1、已知标题,发现Coil在宫格多时间,如果直接:
- mImageLoader?.enqueue(request)
复制代码 也有肯定小的耗时。以是干脆用协程包装起来。
2、固然通过设置内存系数
- availableMemoryPercentage
复制代码 扩大了内存,但跑起来发现设置后内存照旧比力小(约300mb),这是不敷的,必要通过其他设置方式扩大内存空间。
3、app跑起来后,没有在当前app的硬盘缓存空间发现图片解码后的磁盘文件缓存陈迹。这必要再设置。
Android图片加载框架Coil,Kotlin-CSDN博客文章欣赏阅读649次。Coil是专门针对Android平台上的Kotlin语言特性操持,这不像Glide,Glide的焦点框架语言是Java。Coil实现看更细颗粒度的内存、磁盘缓存的客制化设置。https://blog.csdn.net/zhangphil/article/details/145558324
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |