Glide加载圆形图片报错:java.lang.AbstractMethodError: abstract method "void com.bumptech.glide.load.Key.updat

本文介绍了Glide的基本用法,并针对在加载圆形图片时遇到的`java.lang.AbstractMethodError`问题进行了深入讨论。Glide是Google推荐的图片加载工具,支持多种图片资源加载。在尝试使用第三方库加载圆形图片时遇到错误,解决方案包括自定义处理方法或修改源码。文章提供了一个可行的处理方法。

Glide是Google公司在2014年的I/O大会上发布的,到现在有3年左右了,最先版本已经到了4.0以上了。而现在Android上的图片加载框架非常成熟,从最早的老牌图片加载框架UniversalImageLoader,到后来Google推出的Volley,再到后来的新兴军Glide和Picasso,当然还有Facebook的Fresco。而Glide是目前谷歌公司推荐的图片加载工具,好,那我们就现在来了解下Glide。

Glide基本用法

使用前,先添加依赖

dependencies {
    compile 'com.github.bumptech.glide:glide:3.5.2'
    compile 'com.android.support:support-v4:22.0.0'
}

对,上面还要添加v4的依赖,Glide需要依赖Support Library v4,别忘了。其实Support Library v4已经是应用程序的标配了,这不是什么问题。
网络加载图片,可别忘了添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

现在先准备张图片:
http://imgsrc.baidu.com/baike/pic/item/d01373f082025aaf520fb3e9f9edab64034f1ad7.jpg

加载图片,一行代码:


 String url = "http://imgsrc.baidu.com/baike/pic/item/d01373f082025aaf520fb3e9f9edab64034f1ad7.jpg";
        Glide.with(this).load(url).into(imageView);

首先,调用Glide.with()方法用于创建一个加载图片的实例。with()方法可以接收Context、Activity或者Fragment类型的参数。也就是说我们选择的范围非常广,不管是在Activity还是Fragment中调用with()方法,都可以直接传this。那如果调用的地方既不在Activity中也不在Fragment中呢?也没关系,我们可以获取当前应用程序的ApplicationContext,传入到with()方法当中。注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。

接下来看一下load()方法,这个方法用于指定待加载的图片资源。Glide支持加载各种各样的图片资源,包括网络图片、本地图片、应用资源、二进制流、Uri对象等等。因此load()方法也有很多个方法重载,除了我们刚才使用的加载一个字符串网址之外,你还可以这样使用load()方法:

// 加载本地图片
File file = new File(getExternalCacheDir() + "/image.jpg");
Glide.with(this).load(file).into(imageView);

// 加载应用资源
int resource = R.drawable.image;
Glide.with(this).load(resource).into(imageView);

// 加载二进制流
byte[] image = getImageBytes();
Glide.with(this).load(image).into(imageView);

// 加载Uri对象
Uri imageUri = getImageUri();
Glide.with(this).load(imageUri).into(imageView);

当然Glide还有其他一些常用的方法,比如:

Glide.with(this)
     .load(url)
     .asBitmap()//以图片的形式展示,还有asGif()方法,加载gif图片
     .placeholder(R.drawable.loading)//占位图
     .error(R.drawable.error)//加载出错时的图片
     .override(100, 100)//指定设置图片大小
     .diskCacheStrategy(DiskCacheStrategy.NONE)//缓存策略
     .into(imageView);

其中需要注意的是asBitmap()方法,这个方法的意思就是说这里只允许加载静态图片,不需要Glide去帮我们自动进行图片格式的判断了。其他图片加载设置项方法,可以通过RequestOptions类去进行设置。

设置监听器

Glide.with(this).load(internetUrl).listener(new RequestListener<String, GlideDrawable>() {   
        @Override   
        public boolean onException(Exception e, String model,   Target<GlideDrawable> target, boolean isFirstResource) {    
                  return false;  
 }   
   //这个用于监听图片是否加载完成   
   @Override   
    public boolean onResourceReady(GlideDrawable resource String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {    
                    return false;   
    }  
}).into(imageView);

缓存策略

//Glide支持多种磁盘缓存策略:
DiskCacheStrategy.NONE :不缓存图片 
DiskCacheStrategy.SOURCE :缓存图片源文件 
DiskCacheStrategy.RESULT:缓存修改过的图片 
DiskCacheStrategy.ALL:缓存所有的图片,默认
//清理缓存
Glide.get(context).clearDiskCache();

好了,上面的基础先到这里了。

下面是本文的重点,是我在使用中报的一个错,就是在使用加载圆形图的时候的出错。这里说下,加载圆形图的时候,有2个选择,一个是自定义写的,一个是利用老外封装的一个依赖包,但是这个依赖包现在报的就是这个错。先说说是如何使用的吧。
1. 添加依赖

 // Glide图形转换工具
    compile 'jp.wasabeef:glide-transformations:2.0.1'

2.使用

// 使用构造方法 CropCircleTransformation(Context context)
     Glide.with(this)
      .load(url)
      .bitmapTransform(new CropCircleTransformation(this))
      .into(mImageView2);

听从网上的一些建议,用上面的依赖库,使用时出错了。这时候就会报出下面的错:

java.lang.AbstractMethodError: abstract method "void com.bumptech.glide.load.Key.updateDiskCacheKey(java.security.MessageDigest)"

需要在里面实现一个抽象方法,但是目前因为是依赖包,你无法进行修改源码,所以那有两种方式,一是下载源码,重新编写,一种是自己写个处理方法。
下面的这个处理方法,经过测试,可行。

/**
*
* des: 将图片转化为圆形
*/
public class GlideCircleTransform extends BitmapTransformation {
    public GlideCircleTransform(Context context) {
        super(context);
    }

    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        // TODO this could be acquired from the pool too
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override public String getId() {
        return getClass().getName();
    }
}

使用

 Glide.with(this).glideRequet.load(url).transform(new GlideCircleTransform(context)).into(imageView);
<think>嗯,用户遇到了Java中的ClassNotFoundException,具体是找不到com.bumptech.glide.R$id类。这个问题可能出现在使用Glide库的时候。首先,我应该回忆一下Glide的常见问题,特别是资源ID相关的。 首先,用户可能在构建过程中没有正确生成Glide的R类。这可能是因为项目中没有正确配置Glide的注解处理器。Glide v4及以上版本需要使用注解处理器生成一些代码,所以需要检查build.gradle文件中的依赖是否正确添加了annotationProcessor。 然后,可能涉及到依赖冲突或者版本不兼容。比如,项目中可能引用了不同版本的Glide库,或者有其他库也包含了Glide的类,导致冲突。这时候需要检查依赖树,使用./gradlew app:dependencies命令看看是否有重复的Glide依赖,排除掉重复的。 另外,资源清理的问题也有可能。有时候,清理项目后重新构建可能会解决问题,因为旧的生成文件可能残留导致问题。建议用户执行Clean Project和Rebuild Project操作。 还有可能用户的布局文件中引用了Glide的某个资源ID,但Glide的R类没有被正确生成,导致运行时找不到。需要确认是否在代码中错误地引用了Glide的R类,比如com.bumptech.glide.R.id某个ID,而实际上应该使用自己应用的R类。 此外,多模块项目中的配置问题也可能导致这种情况。如果项目有多个子模块,需要确保主模块正确依赖了Glide,并且所有模块的Glide版本一致。 最后,考虑是否启用了ProGuard或R8混淆,导致Glide的R类被错误移除。需要检查混淆规则,确保保留Glide的相关类。 总结可能的解决步骤:检查Glide依赖是否正确包含注解处理器,排除重复依赖,清理并重新构建项目,检查资源引用是否正确,处理多模块依赖,调整混淆规则。</think>### 解决 `ClassNotFoundException: com.bumptech.glide.R$id` 的步骤 #### 1. **检查 Glide 依赖配置** Glide 需要正确引入核心库和注解处理器。在 `build.gradle` 中添加以下依赖: ```groovy dependencies { implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' } ``` 确保 `annotationProcessor` 配置正确,否则无法生成 `R$id` 类[^1]。 #### 2. **处理依赖冲突** 若项目中存在多个 Glide 版本或其他库冲突(如重复的 `GifDecoder$BitmapProvider.class`),需排查并排除重复依赖: ```groovy configurations { all { exclude group: 'com.bumptech.glide', module: 'glide' } } ``` 使用 `./gradlew app:dependencies` 查看依赖树[^2]。 #### 3. **清理并重新构建项目** - 执行 **Clean Project**(Android Studio: `Build > Clean Project`) - 执行 **Rebuild Project**(Android Studio: `Build > Rebuild Project`) #### 4. **验证资源引用** 确保代码中未错误引用 Glide 的 R 类,例如: ```java // 错误示例:直接引用 Glide 的 R 类 import com.bumptech.glide.R; // 正确应使用应用自身的 R 类 import com.yourpackage.R; ``` #### 5. **多模块项目配置** 若项目包含多个模块,需在主模块的 `build.gradle` 中声明 Glide 依赖,并确保所有模块使用相同版本。 #### 6. **检查混淆规则** 在 `proguard-rules.pro` 中添加以下规则,防止 Glide 类被混淆: ``` -keep public class com.bumptech.glide.** { *; } -keep public class com.bumptech.glide.R$** { *; } ``` #### 7. **更新 Android Gradle 插件** 在 `build.gradle` 中确保使用兼容的 Gradle 插件版本: ```groovy classpath 'com.android.tools.build:gradle:7.0.0' // 或更高版本 ``` --- ### 相关问题 1. **Glide 图片加载失败时如何显示占位图?** 使用 `Glide.with(context).load(url).placeholder(R.drawable.placeholder).error(R.drawable.error).into(imageView);` 配置占位符和错误图。 2. **如何解决 Glide 缓存策略导致图片不更新的问题?** 通过 `diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)` 禁用缓存[^4]。 3. **Glide 如何处理大图或内存溢出(OOM)?** 使用 `override(width, height)` 限制加载尺寸,或通过 `Downsampler` 调整采样率。 --- 以上步骤可覆盖大多数 `ClassNotFoundException` 场景,若问题仍存在,需结合具体日志和项目结构进一步分析[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值