项目地址GlideV4
刚写完这篇文章突然想起来是不是可以使用接口来代替Picture这样可以更加通用,于是试了一下果然可以.所以读者们可以将Picture替换成IPicture接口.
public interface IPicture {
String getFileName();
}
前面介绍了如何使用Glide3.x 进行图片文件加密解密.最近Glide更新到了4.x conceal也更新到了2.x , 所以决定把自己的项目更新到最新版本.
如果您使用的是 Glide 3.x请看这篇文章使用Glide 3.x 自定义GlideModel和 conceal 1.x 对Android[图片]文件加密与解密
Glide4.x 相对于Glide 3.x变化还是挺大的
在此我们先来了解一下Glide 4.x 在使用上的一些变化
一些变化
一. 引用库的变化,这个不用解释了吧! 升级版本....
compile 'com.github.bumptech.glide:glide:4.0.0-RC1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0-RC1'
compile 'com.facebook.conceal:conceal:2.0.1@aar'
二. 接口上的变化
Glide.with()
4.x 新增了一个重载Glide.with(view)
是的你没有看错,可以使用View作为参数. 而且还会将你的图片加载与Activity或者是Fragment生命周期进行绑定. 当然使用这个接口会耗费那么多一点点的性能.但是为了更好的封装(在Adapter中再也不需要专门为Glide传一个Fragment或Activity参数了)这一点性能牺牲还是值得的.图片变换比如裁切,圆角等. 在Glide 3.x 时代我们使用类似如下代码
Glide.with(context)
.load("")
.bitmapTransform(new CenterCrop(context), new CropCircleTransformation(context))
.into(image);
而我们在4.x中则应该以一种新的姿态来实现,centerCrop()placeholder()error()priority()
diskCacheStrategy()等大多数方法都被移动到了RequestOptions中,glide-transformations
4.x 中已经不能再使用了, 如果需要使用可以复制源代码进行修改. 或者等作者更新.
- 总之一句话原来找不到的接口,就去
RequestOptions
中找. 找不到了那我也没辙啊. 比如动画接口..animate()
RequestOptions mOptions = RequestOptions.circleCropTransform();
Glide.with(context)
.load("")
.apply(mOptions)
.into(image);
Glide 4.x 自定义GlideModel
Glide 4.x 不再需要像 Glide 3.x 那样在主配置文件里面配置 GlideModel,只需要在GlideModel类加上注解即可.
为了不影响原来的URL类型图片处理所以这里注册的是Picture类型和文件类型
两者实现一个即可.具体的说明可以在注释中看到.就不再解释了
/**
* Glide 4.x 自定义处理Picture类型和File类型的文件处理, GlideModel
*/
@GlideModule public class MyGlideModule extends AppGlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
// 设置别的get/set tag id,以免占用View默认的
ViewTarget.setTagId(R.id.glide_tag_id);
RequestOptions options = new RequestOptions().format(DecodeFormat.PREFER_RGB_565);
builder.setDefaultRequestOptions(options);
}
@Override public void registerComponents(Context context, Registry registry) {
// 指定Model类型为Picture的处理方式
registry.append(Picture.class, InputStream.class, new MyModelLoader.LoaderFactory());
// 指定Model类型为File的处理方式
registry.append(File.class, InputStream.class,
new FileLoader.Factory(new FileLoader.FileOpener() {
@Override public InputStream open(File file) throws FileNotFoundException {
// 可以在这里进行文件处理,比如解密等.
Timber.e(file.getAbsolutePath());
return ConcealUtil.getCipherInputStream( new FileInputStream(file));
}
@Override public void close(InputStream inputStream) throws IOException {
inputStream.close();
}
@Override public Class getDataClass() {
return InputStream.class;
}
}));
}
/**
* 清单解析的开启
*
* 这里不开启,避免添加相同的modules两次
*
* @return
*/
@Override public boolean isManifestParsingEnabled() {
return false;
}
}
图片文件的解密都在这里进行.
**
* Glide 4.x 自定义GlideModel
* 这里指定Picture类型的Model由用户处理
*/
public class MyModelLoader implements ModelLoader
祭出我们的Util代码
特别留意一下这一句代码,与3.x是有区别的.当然3.x也可以使用这段代码来初始化crypto.
crypto = AndroidConceal.get()
.createDefaultCrypto(new SharedPrefsBackedKeyChain(context, CryptoConfig.KEY_256));
public class ConcealUtil {
private static Crypto crypto = null;
private static Entity entity = null;
/**
* 初始化
*
* @param context context
* @param e 密码
*/
public static void init(Context context, String e) {
entity = Entity.create(e);
crypto = new Crypto(new SharedPrefsBackedKeyChain(context, CryptoConfig.KEY_256),
new SystemNativeCryptoLibrary(), CryptoConfig.KEY_256);
if (!crypto.isAvailable()) {
destroy();
}
}
public static void destroy() {
crypto = null;
entity = null;
}
private static void check() {
if (crypto == null || entity == null) {
throw new RuntimeException("请初始化.....");
}
}
public static OutputStream getCipherOutputStream(File file) {
if (file.exists()) return null;
try {
OutputStream fileStream = new FileOutputStream(file);
return getCipherOutputStream(fileStream);
} catch (IOException e) {
Timber.e(e);
}
return null;
}
public static OutputStream getCipherOutputStream(OutputStream fileStream) {
check();
try {
return crypto.getCipherOutputStream(fileStream, entity);
} catch (IOException e) {
Timber.e(e);
} catch (CryptoInitializationException e) {
Timber.e(e);
} catch (KeyChainException e) {
Timber.e(e);
}
return null;
}
public static InputStream getCipherInputStream(String file) {
return getCipherInputStream(new File(file));
}
public static InputStream getCipherInputStream(File file) {
check();
if (!file.exists()) return null;
try {
InputStream inputStream = new FileInputStream(file);
return crypto.getCipherInputStream(inputStream, entity);
} catch (FileNotFoundException e) {
Timber.e(e);
} catch (KeyChainException e) {
Timber.e(e);
} catch (CryptoInitializationException e) {
Timber.e(e);
} catch (IOException e) {
Timber.e(e);
}
return null;
}
/**
* 保存字节流
*
* @param data 数据
*/
public static void saveFile(byte data[], String path) {
String fileName = System.currentTimeMillis() + ".jpg";
File image = new File(path, fileName);
try {
OutputStream outStream = getCipherOutputStream(image);
if (outStream != null) {
outStream.write(data);
outStream.flush();
outStream.close();
}
} catch (IOException e) {
Timber.e(e);
}
}
}
使用方式,注意一定只能load(picture)
GlideApp.with(this).load(new Picture()).into(mImageView);
项目地址GlideV4