图片加载时项目中不可缺少的一个功能,很多程序员都会使用一些框架来帮助处理要加载的图像,往往在处理图片加载时很有可能会出现OOM的错误,这样会很蛋疼。现在主流的都是使用ImageLoader、Volley、Picasso,或者是一些自己封装的工具类。最近我发现一个新的图片加载框架Fresco是faceBook中使用的强大框架,代码简洁功能强大,可以很好的解决OOM的现象。
具体的配置我就略过,直接进入使用环节,如果想了解的话这是Fresco的官网(中文的)https://www.fresco-cn.org/docs/index.html
加载图片代码很简单,首先要在继承Application类里初始化
在MainActivity类里直接可以加载URLset到ImageView上,这里注意Fresco不接受相对路径,只能传绝对路径。
到这里我们代码功能就实现了,接下来是xml文件的设置
Fresco使用的是自定义的ImageView,里面的fresco标签要加上红框内的才可以(这里有个坑就是fresco的自定义属性不能提示,只能自己查官网复制,可能有的人能提示具体我还不太清楚为什么)
接下来是一些常用的自定义属性的具体意义和使用注意
public class FrescoUtil {
private static final String TAG = "FrescoUtil";
public static final String IMAGE_PIC_CACHE_DIR = Environment.getExternalStorageDirectory().getPath()+"/AndroidIamge/";
/**
* 保存图片
*
* @param activity
* @param picUrl
*/
public static void savePicture(String picUrl,Context context) {
File picDir = new File(IMAGE_PIC_CACHE_DIR);
if (!picDir.exists()) {
picDir.mkdir();
}
CacheKey cacheKey = DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(ImageRequest.fromUri(Uri.parse(picUrl)),context);
File cacheFile = getCachedImageOnDisk(cacheKey);
if (cacheFile == null) {
downLoadImage(Uri.parse(picUrl),"down",context);
return;
} else {
copyTo(cacheFile,picDir,"down");
}
}
public static File getCachedImageOnDisk(CacheKey cacheKey) {
File localFile = null;
if (cacheKey != null) {
if (ImagePipelineFactory.getInstance().getMainDiskStorageCache().hasKey(cacheKey)) {
BinaryResource resource = ImagePipelineFactory.getInstance().getMainDiskStorageCache().getResource(cacheKey);
localFile = ((FileBinaryResource) resource).getFile();
} else if (ImagePipelineFactory.getInstance().getSmallImageDiskStorageCache().hasKey(cacheKey)) {
BinaryResource resource = ImagePipelineFactory.getInstance().getSmallImageDiskStorageCache().getResource(cacheKey);
localFile = ((FileBinaryResource) resource).getFile();
}
}
return localFile;
}
/**
* 复制文件
*
* @param src 源文件
* @param dst 目标文件
* @return
*/
public static boolean copyTo(File src, File dir, String filename) {
FileInputStream fi = null;
FileOutputStream fo = null;
FileChannel in = null;
FileChannel out = null;
try {
fi = new FileInputStream(src);
in = fi.getChannel();//得到对应的文件通道
File dst;
dst = new File(dir, filename + ".jpg");
fo = new FileOutputStream(dst);
out = fo.getChannel();//得到对应的文件通道
in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道
return true;
} catch (IOException e) {
return false;
} finally {
try {
if (fi != null) {
fi.close();
}
if (in != null) {
in.close();
}
if (fo != null) {
fo.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
public static void downLoadImage(Uri uri, final String filename, Context context) {
ImageRequest imageRequest = ImageRequestBuilder
.newBuilderWithSource(uri)
.setProgressiveRenderingEnabled(true)
.build();
ImagePipeline imagePipeline = Fresco.getImagePipeline();
DataSource>
dataSource = imagePipeline.fetchDecodedImage(imageRequest, context);
dataSource.subscribe(new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(Bitmap bitmap) {
if (bitmap == null) {
Log.e(TAG,"保存图片失败啦,无法下载图片");
}
File appDir = new File(IMAGE_PIC_CACHE_DIR);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = filename + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
assert bitmap != null;
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailureImpl(DataSource dataSource) {
}
}, CallerThreadExecutor.getInstance());
}
}
然后我们在加载时候改造一下
这样图片就会加载到本地了,具体路径和文件名字可以自行去更改