Android开发中使用Glide V4 中Generated API特性
来源:互联网 发布:学java入门什么书推建 编辑:程序博客网 时间:2024/05/20 11:35
Android Glide4 异步图片框架
简介篇: Glide框架
迁移篇:Glide V4 框架新特性(Migrating from v3 to v4)
基础篇:Android开发中使用Glide V4 中Generated API特性
常用篇:Android Glide设置默认图片、异常图片为圆形图片
- 进级篇:Kotlin编程开发之Glide V4使用OkHttp3作为传输层
实战项目案例
- Kotlin Android Extensions+Android MVP项目(RxJava+Rerotfit+OkHttp+Glide)
- Anko Layout+MVP(Glide,Retrofit,OkHttp,RxJava)开发Android运用程序
Google在2013年发布了网络文本和图片异步加载的Volley框架,而在2014年的Google IO app中推举Glide框架来加载图片。这说明,Glide比起Volley中ImageRequst更具备优势,节省内存和节省宽带数据。
这里,Volley框架和Glide框架用加载同样的网络资源,进行比较了一番。
RecyclerView中使用Volley的NetWorkImageView的内存情况:
RecyclerView中ImageView使用Glide的内存情况:
若是不熟悉Glide框架使用情况,可以阅读Glide 框架和Glide v4新特性。
使用Glide v4中的Generated API 开发
前期配置,在项目中Gradle中引入库的依赖:
dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:design:25.3.1' compile 'com.android.support:recyclerview-v7:25.3.1' //Glide框架引入 compile 'com.github.bumptech.glide:glide:4.0.0-RC0' annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0-RC0'}
自定义AppGlideModule:
为运用程序定义一个带有@GlideModule
注解的AppGlideModule,运用程序会使用和AppGlideMoudle同一个包下的GlideApp类。通过GlideApp.with()
方式使用Glide的Generated API。
@GlideModulepublic final class CustomAppGlideModule extends AppGlideModule{ /** * 通过GlideBuilder设置默认的结构(Engine,BitmapPool ,ArrayPool,MemoryCache等等). * @param context * @param builder */ @Override public void applyOptions(Context context, GlideBuilder builder) { //重新设置内存限制 builder.setMemoryCache(new LruResourceCache(10*1024*1024)); } /** * 为App注册一个自定义的String类型的BaseGlideUrlLoader * * @param context * @param registry */ @Override public void registerComponents(Context context, Registry registry) { registry.append(String.class, InputStream.class,new CustomBaseGlideUrlLoader.Factory()); } /** * 清单解析的开启 * * 这里不开启,避免添加相同的modules两次 * @return */ @Override public boolean isManifestParsingEnabled() { return false; }}
注意点:
- 必需带有
@GlideModule
注解。 isManifestParsingEnabled()
返回false,关闭解析AndroidManifest,不需要再配置GlideModule.
自定义BaseGlideUrlLoader:
根据带有图片尺寸的URl,来获取合适比例的图片资源。通过指定String类型的Model, BaseGliUrlLOader中getgetURL()
来覆盖原本的带有http或者htpps的URL. 这里处理方式来源于,Google IO App.
public class CustomBaseGlideUrlLoader extends BaseGlideUrlLoader<String> { private static final ModelCache<String, GlideUrl> urlCache = new ModelCache<>(150); /** * Url的匹配规则 */ private static final Pattern PATTERN = Pattern.compile("__w-((?:-?\\d+)+)__"); public CustomBaseGlideUrlLoader(ModelLoader<GlideUrl, InputStream> concreteLoader,ModelCache<String, GlideUrl> modelCache) { super(concreteLoader,modelCache); } /** * If the URL contains a special variable width indicator (eg "__w-200-400-800__") * we get the buckets from the URL (200, 400 and 800 in the example) and replace * the URL with the best bucket for the requested width (the bucket immediately * larger than the requested width). * * 控制加载的图片的大小 */ @Override protected String getUrl(String model, int width, int height, Options options) { Matcher m = PATTERN.matcher(model); int bestBucket = 0; if (m.find()) { String[] found = m.group(1).split("-"); for (String bucketStr : found) { bestBucket = Integer.parseInt(bucketStr); if (bestBucket >= width) { // the best bucket is the first immediately bigger than the requested width break; } } if (bestBucket > 0) { model = m.replaceFirst("w"+bestBucket); } } return model; } @Override public boolean handles(String s) { return true; } /** * 工厂来构建CustormBaseGlideUrlLoader对象 */ public static class Factory implements ModelLoaderFactory<String,InputStream>{ @Override public ModelLoader<String, InputStream> build(MultiModelLoaderFactory multiFactory) { return new CustomBaseGlideUrlLoader(multiFactory.build(GlideUrl.class,InputStream.class),urlCache); } @Override public void teardown() { } }}
ProGuard Rules中添加混淆规则:
根据上面的自定义,保持AppGlideModule子类和GlideModule实现类不被混淆。
#Glide的混淆规则-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 *;}
使用权限 : 联网权限,读写权限,AndroidManifest.xml中自行配置。
确保GlideApp类正常引用:
当配置完以上步骤后,发觉不能使用GlideApp类。
解决方式:在AndroidStudio中Build–>Make Project
–>将会出现build/generated/source中,便可以使用GlideApp
使用GlideApp类用于各种场景:
1. 单个ImageView加载图像资源:
Url:https://www.baidu.com/img/bd_logo1.png
Uri:content://media/external/images/1
Resource Id :R.drawable.image或者R.mipmap.ic_launcher
当然,还有其他的图像资源。
加载本地图片:
/** * 加载本地图片,这里是mipmap文件夹下的资源 */ private void loadLocalImage() { RequestBuilder<Drawable> drawableRequestBuilder = GlideApp.with(this).load(R.mipmap.ic_launcher); drawableRequestBuilder.into(this.local_iv); }
加载网络图片:
/** * 从远程网路上加载图片 */ private void loadRemoteImage() { GlideApp.with(this).asBitmap() .load(ImageResouce.imageResource[0]) .error(R.mipmap.ic_launcher)//占位图片 .placeholder(R.mipmap.ic_launcher)//异常图片 .into(this.remote_iv); }
预先下载,本地缓存中加载:
/** * 预先加载资源 */ private void startPreload() { GlideApp.with(this).asBitmap() .load(ImageResouce.imageResource[1]) .diskCacheStrategy(DiskCacheStrategy.ALL) .preload(); } /** * 预先下载原始图片资源后,本地加载 */ private void loadPreloadImage() { GlideApp.with(this).asBitmap().load(ImageResouce.imageResource[1]).diskCacheStrategy(DiskCacheStrategy.ALL).into(this.preload_iv); }
error 和placeholder的处理:
.error(R.mipmap.ic_launcher) //异常图片 .placeholder(R.mipmap.ic_launcher) //占位图片 .fallback(R.mipmap.ic_launcher); //当url为空时,回调显示的图片
2. RecyclerView(或者ListView,GridView)中加载图片资源:
Glide单一要求是任何重复使用的View Target,调用Clear()API明确清除先前的加载,以防加载到旧数据。
@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { ImageView imageView=holder.getImageView(); String url=imageList.get(position); if(TextUtils.isEmpty(url)){ //清空旧数据的引用 GlideApp.with(context).clear(imageView); //当资源为空时候,设置默认图片 imageView.setImageResource(R.mipmap.ic_launcher); }else{//开启一个图片加载 loadImage(url,imageView); }} /** * 加载图片 * @param url * @param imageView */public void loadImage(String url,ImageView imageView){ RequestBuilder<Bitmap> bitmapRequestBuilder= GlideApp.with(context) .asBitmap()//指定Bitmap类型的RequestBuilder .load(url)//网络URL .error(R.mipmap.ic_launcher)//异常图片 .placeholder(R.mipmap.ic_launcher)//占位图片 .fallback(R.mipmap.ic_launcher);//当url为空时,显示图片 bitmapRequestBuilder.into(imageView);}
3. 自定义Circle Transformation 实现圆角图片:
Glide拥有两个默认的转换(transformation):
- Fit center:类似Android’s ScaleType.FIT_CENTER
- Center crop:类似Android’s ScaleType.CENTER_CROP
这里继承BitmapTransformation,复写transform()
:
public class CircleTransform extends BitmapTransformation{ public CircleTransform(Context context){ super(context); } /** * 重写 生成圆角图片 * @param pool * @param toTransform * @param outWidth * @param outHeight * @return */ @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull 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; 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 void updateDiskCacheKey(MessageDigest messageDigest) { }}
Glide使用自定义的Transform,最后将圆形Bitmap加载到ImageView上:
/** * 加载图片 * @param url * @param imageView */ public void loadImage(String url,ImageView imageView){ RequestBuilder<Bitmap> bitmapRequestBuilder= GlideApp.with(context) .asBitmap()//指定Bitmap类型的RequestBuilder .load(url)//网络URL .error(R.mipmap.ic_launcher)//异常图片 .placeholder(R.mipmap.ic_launcher)//占位图片 .fallback(R.mipmap.ic_launcher);//当url为空时,显示图片 RequestOptions requestOptions=new RequestOptions(); //在RequestOptions中使用Transformations requestOptions.transform(new CircleTransform(context)); //RequestBuilder<Bitmap> 中添加RequestOptions bitmapRequestBuilder.apply(requestOptions).into(imageView); }
4. 自定义BitmapImageViewTarget实现圆角图片:
自定义一个BitmapImageViewTarget,复写setResource()
:
public class CircularBitmapImageViewTarget extends BitmapImageViewTarget { private Context context; private ImageView imageView; public CircularBitmapImageViewTarget(Context context,ImageView view) { super(view); this.context=context; this.imageView=view; } /** * 重写 setResource(),生成圆角的图片 * @param resource */ @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable bitmapDrawable= RoundedBitmapDrawableFactory.create(this.context.getResources(),resource); /** * 设置图片的shape为圆形. * * 若是需要制定圆角的度数,则调用setCornerRadius()。 */ bitmapDrawable.setCircular(true); this.imageView.setImageDrawable(bitmapDrawable); }}
Glide使用自定义ViewTarget:
/** * 加载图片 * @param url * @param imageView */ public void loadImage(String url,ImageView imageView){ RequestBuilder<Bitmap> bitmapRequestBuilder= GlideApp.with(context) .asBitmap()//指定Bitmap类型的RequestBuilder .load(url)//网络URL .error(R.mipmap.ic_launcher)//异常图片 .placeholder(R.mipmap.ic_launcher)//占位图片 .fallback(R.mipmap.ic_launcher);//当url为空时,显示图片 //在RequestBuilder<Bitmap> 中使用自定义的ImageViewTarget bitmapRequestBuilder.into(new CircularBitmapImageViewTarget(context,imageView)); }
项目运行效果如下:
项目代码链接:https://github.com/13767004362/GlideDemo
资源汇总:
Glide 框架: http://blog.csdn.net/hexingen/article/details/72577453
Glide 3.x到4.x的变化:http://blog.csdn.net/hexingen/article/details/72578066
Kotlin编程中 Glide V4与OkHttp3自定义集成使用
问题汇总:
在listView或者RecyclerView中使用Glide框架,内存剧增或者爆内存溢出(OutOfMemoryError):
原因:在ImageView中scaleType使用了fitxy属性:
<ImageView android:id="@+id/item_movielist_iv" android:layout_width="100dp" android:layout_height="100dp" android:scaleType="fitXY"/>
将fitXY改动成:fitCenter 或者centerCrop,内存情况如下:
解决方式最终来源:https://github.com/bumptech/glide/issues/464
解决同一URL远程图片,多次按不同大小比例加载多次加载的问题:
Preload Images,将URL对应的数据源即原图保存下载,下次按比例来本地加载:
diskCacheStrategy(DiskCacheStrategy.ALL)
- Android开发中使用Glide V4 中Generated API特性
- Kotlin编程之Glide v4 Generated API(Unresolved reference GlideApp)
- Eclipse中查看android-support-v4 API
- Glide V4的封装使用
- android开发中出现R.java was modified manually! Reverting to generated version!问题的解决方法
- 【Android开发】eclipse中如何关联v4包源码?
- Android中Glide(加载图片)的使用
- Android中图片加载框架Glide的使用
- Android应用开发中如何使用隐藏API
- Android应用开发中如何使用隐藏的API
- Android应用开发中如何使用隐藏API
- Android应用开发中如何使用隐藏API
- Android应用开发中如何使用隐藏API
- Android应用开发中如何使用隐藏的API
- Android应用开发中如何使用隐藏API
- Android中使用Geocoding API
- Android之Glide使用详解--集成、配置、使用、特性
- Android Studio 中使用Java 8 特性
- 【备忘】IBM DB2视频教程下载
- CF
- React Native之TextInput组件实现联想输入
- python-Windows下Anaconda2(Python2)和Anaconda3(Python3)的共存
- C/C++时间函数使用方法
- Android开发中使用Glide V4 中Generated API特性
- Iphone隐藏和显示TabBar的方法
- 简单介绍浏览器端的几种存储技术
- 查找兄弟单词
- 最大子数组和算法(Java实现)
- oracle chr()(附常用字符与ascii对照表)
- 脚本的最大优势,就是简化工作步骤提高工作效率,你看出来了吗?有没有看到这段代码的作用呢?
- 【OpenGL】安装配置
- nio按行读文件