Glide v4 Generated API(Unresolved reference GlideApp) for Kotlin programming

Keywords: Android Java Programming github

Kotlin Programming Development Android Application Program Related Introduction:

Using Glide v4 Generated API in Kotlin programming

Preliminary preparation:

Refer to the Glide Library in Gralde:

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'
    testCompile 'junit:junit:4.12'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    //Glide v4
    compile 'com.github.bumptech.glide:glide:4.0.0-RC0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0-RC0'
}

The confusion rule:

#Glide's confusion rules
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
    **[] $VALUES;
    public *;
}

Start coding

Start with Kotlin programming, related Glide v4 Generated API configuration.

Customize AppGlideModule:

@GlideModule
internal class CustomAppGlideModule : AppGlideModule() {
    /**
     * Setting memory cache size 10M
     */
    val  cacheSize=10*1024*1024
    override fun applyOptions(context: Context?, builder: GlideBuilder) {
        builder.setMemoryCache(LruResourceCache(cacheSize))
    }

    /**
     * Register a BaseGlideUrlLoader of String type
     */
    override fun registerComponents(context: Context?, registry: Registry) {

        registry.append(String::class.java,InputStream::class.java, 
             CustomBaseGlideUrlLoader.factory)
    }

    /**
     * Close parsing Android Manifest
     */
    override fun isManifestParsingEnabled(): Boolean {
        return false
    }

}

To define an AppGlideModule with the @GlideModule annotation for the application, the application uses the GlideApp class under the same package as AppGlideMoudle. Use Glide's Generated API through GlideApp.with().

Customize BaseGlideUrlLoader:

internal class CustomBaseGlideUrlLoader(concreteLoader: ModelLoader<GlideUrl, InputStream>, modelCache: ModelCache<String, GlideUrl>): BaseGlideUrlLoader<String>(concreteLoader,modelCache){
    /**
     * Url The matching rules of 6550
     */
     val patern= Pattern.compile("__w-((?:-?\\d+)+)__")
    /**
     * Control the size of the image to be loaded
     */
    override fun getUrl(model: String, width: Int, height: Int, options: Options?): String {
      var  m=patern.matcher(model)
        var bestBucket=0
        if (m.find()){
           var  found=m.group(1).split("-")
            for (item in found){
                bestBucket=item.toInt()
                if (bestBucket>=width) break
            }
        }
        return model
    }
    override fun handles(model: String?)=true
    companion object{
        val urlCache= ModelCache<String, GlideUrl>(150)
        /**
         * The default is private and exposed to Java calls through the @JvmField annotation
         */
        @JvmField
        val factory=object: ModelLoaderFactory<String, InputStream> {
            override fun build(multiFactory: MultiModelLoaderFactory) 
                  : ModelLoader<String, InputStream> { 

                     return CustomBaseGlideUrlLoader( 
                          multiFactory.build(GlideUrl::class.java, InputStream::class.java), urlCache)
            }
            override fun teardown() {
            }
        }
    }
}

According to the URl with picture size, the appropriate proportion of image resources can be obtained. By specifying a String-type Model, the getget URL () in BaseGliUrlLOader overrides the original URL with http or htpps. This process is based on Google IO App.

Configuration has been completed, and the GlideApp class has been happily used to load images onto ImageView:

 GlideApp.with(context).asBitmap()
         .load(url)
         .error(R.mipmap.ic_launcher)
         .placeholder(R.mipmap.ic_launcher)
         .into(CircularBitmapImageViewTarget(context,imageView));

Just after the GlideApp class was written happily, you ran the project and found that Android Studio gave you an error report:

Unresolved reference: GlideApp

Nani, using Glide V4 in Java is good. Why not Kotlin?

Unfortunately, I searched for questions in the Glide project on Github and found that I was not alone in this problem. Click here for details.

Note: Currently, GlideApp references are not available in Kotlin programming.

At this time, I felt tears running away and deeply hit my young mind. Fortunately, Kotlin is still powerful, 100% Java compatible. If Kotlin can't write it, use Java.

Curve Save the Nation: Java Language Writes Custom AppGlideModule:

@GlideModule
public class CustomAppGlideModule extends AppGlideModule{
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        //Reset the memory limit, here 10M
        builder.setMemoryCache(new LruResourceCache(10*1024*1024));
    }
    /**
     * Register a custom String type BaseGlideUrlLoader for App
     *
     * @param context
     * @param registry
     */
    @Override
    public void registerComponents(Context context, Registry registry) {
        registry.append(String.class, InputStream.class, CustomBaseGlideUrlLoader.factory);
    }
    /**
     * Close scanning Android Manifests. XML
     * @return
     */
    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }
}

Note: Since the custom BaseGlideUrlLoader is written in Kotlin language, it uses Java to call static fields in Kotlin programming and @JvmField annotation.

internal class CustomBaseGlideUrlLoader(concreteLoader: ModelLoader<GlideUrl, InputStream>, modelCache: ModelCache<String, GlideUrl>): BaseGlideUrlLoader<String>(concreteLoader,modelCache){
     ......
    companion object{
        /**
         * The default is private and exposed to Java calls through the @JvmField annotation
         */
        @JvmField
        val factory=object: ModelLoaderFactory<String, InputStream> {
            ........
        }
    }
}

Successful use of GlideApp classes in projects:

After writing, the Build -> Make Project -> in Android Studio will appear in build/generated/source, and you can use the GlideApp class smoothly.

Use the GlideApp class in ImageView:

The rounded corner image looks better. First, define a Circular Bitmap Image View Target to implement it:

internal class CircularBitmapImageViewTarget(var context: Context, var imageView: ImageView): com.bumptech.glide.request.target.BitmapImageViewTarget(imageView){
    /**
     * Bitmap for drawing rounded corners
     */
   override fun setResource(bitmap: android.graphics.Bitmap?) {
          var bitmapDrawable= RoundedBitmapDrawableFactory.create(context.resources,bitmap)
          bitmapDrawable.isCircular=true
          imageView.setImageDrawable(bitmapDrawable)
    }
}

Write GlideApp invocation method in Java language:

public class GlideUtils {
    public static void loadUrlImage(Context context, String url, ImageView imageView){
        GlideApp.with(context).asBitmap()  
             .load(url).error(R.mipmap.ic_launcher) 
             .placeholder(R.mipmap.ic_launcher) 
             .into(new CircularBitmapImageViewTarget(context,imageView));
    }
}

Finally, in the Adapter of Recycler View, we use:

internal class MovieListAdapter(var context: Context, var list: List<MovieList.Movie>) : RecyclerView.Adapter<MovieListAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)  
         = ViewHolder(View.inflate(parent.context, R.layout.movielist_item, null)) 

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
       //Call Java to write static methods 
       GlideUtils.loadUrlImage(context,list[position].images.large,holder.imageView)
    }
    override fun getItemCount() = list.size
    .......
}

This code is from a case of MVP written in Kotlin language. There are links below.

The results are as follows:

Project code: https://github.com/13767004362/KotlinMVPDemo

Introduction to the Glide Framework:

Posted by ivory_kitten on Sat, 05 Jan 2019 19:06:09 -0800