Leonardo Rocha
Leonardo Rocha

Reputation: 15

How to translate this piece of code from Java to Kotlin?

I'm trying to translate this piece of code from Java to Kotlin. However, I'm struggling with the "super" call of the second constructor that receives an integer as argument.

package info.androidhive.volleyexamples.volley.utils;

import com.android.volley.toolbox.ImageLoader.ImageCache;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class LruBitmapCache extends LruCache<String, Bitmap> implements
        ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public LruBitmapCache() {
        this(getDefaultLruCacheSize());
    }

    public LruBitmapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

I've done this so far. As you can see, LruCache obligates you to pass something as argument. But I want to calculate this argument with the method "getDefaultLruCacheSize".

class LruBitmapCache(var maxSize: Int = 0) : LruCache<String, Bitmap>(maxSize), ImageCache {

    private fun getDefaultLruCacheSize(): Int {
        val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
        return maxMemory / 8
    }

    init {
        maxSize = getDefaultLruCacheSize()
    }

    override fun sizeOf(key: String?, value: Bitmap?): Int = if (value != null) {
            (value.rowBytes * value.height / 1024)
        } else{
            val defaultValue = 1
            defaultValue
        }

    override fun getBitmap(url: String?): Bitmap? = get(url)

    override fun putBitmap(url: String?, bitmap: Bitmap?) {
        put(url, bitmap)
    }

The problem is that with my current approach, the super is called before my init method.

Upvotes: 0

Views: 132

Answers (1)

Francesc
Francesc

Reputation: 29260

You can use @JvmOverloads and use a default value for your cache, so you do not need a 2nd constructor defined explicitly:

class LruBitmapCache @JvmOverloads constructor(
        sizeInKiloBytes: Int = defaultLruCacheSize
) : LruCache<String, Bitmap>(sizeInKiloBytes), ImageCache {

    protected fun sizeOf(key: String, value: Bitmap): Int = value.rowBytes * value.height / 1024

    fun getBitmap(url: String): Bitmap = get(url)

    fun putBitmap(url: String, bitmap: Bitmap) {
        put(url, bitmap)
    }

    companion object {
        val defaultLruCacheSize: Int
            get() {
                val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()

                return maxMemory / 8
            }
    }
}

If you want to use a 2nd constructor, you need to do this

class LruBitmapCache(
        sizeInKiloBytes: Int
) : LruCache<String, Bitmap>(sizeInKiloBytes), ImageCache {

    constructor(): this(defaultLruCacheSize)

    // omitted for brevity
}

Upvotes: 2

Related Questions