Android中的图片加载所出现的问题
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 源图片的高度和宽度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// 计算出实际宽高和目标宽高的比率
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
// 一定都会大于等于目标的宽和高。
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
然后使用控件展示图片就可以了
mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 宽, 高));
/**
* 图片三级缓存操作
* @author Administrator
* */
public class ImageCacheUtil {
private LruCache lruCache;
private File cacheDir;
private ExecutorService newFixedThreadPool;
private Handler mHandler;
public ImageCacheUtil(Context context,Handler handler){
int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);
lruCache = new LruCache(maxSize){
//获取移出图片的大小
@Override
protected int sizeOf(String key, Bitmap value) {
//getRowBytes() : 获取图片一行占用的大小
//getHeight() : 图片的高度,图片占用的行数
return value.getRowBytes()*value.getHeight();
}
};
cacheDir = context.getCacheDir();
newFixedThreadPool = Executors.newFixedThreadPool(5);
this.mHandler = handler;
}
/**
* 根据图片的路径获取图片
* @param url
* @return
*/
public Bitmap display(String url,int position){
//1.先从内存中获取图片.
//LruCache;//key:图片的名称,一般图片的路径,v:value:图片
//缓存到内存中:lruCache.put(url, bitmap);//key:图片的名称 value:图片
//获取缓存的图片
Bitmap bitmap = lruCache.get(url);//key:图片的名称
if (bitmap!=null) {
return bitmap;
}
//2.如果内存中没有,查看本地缓存文件中是否有图片,有,使用,并且再次保存到内存中.
bitmap = getBitmapFromLocal(url);
if (bitmap!=null) {
return bitmap;
}
//3.如果本地缓存文件也没有,只能从网络重新下载,重新保存到本地缓存文件中和内存中.
getBitmapFromNet(url,position);
return null;
}
/**
* 从网络下载图片
* @param url
*/
private void getBitmapFromNet(String url,int position) {
newFixedThreadPool.execute(new RunnableTask(url,position));
}
private class RunnableTask implements Runnable{
private String mUrl;
private int mPosition;
public RunnableTask(String url,int position) {
this.mUrl = url;
this.mPosition = position;
}
@Override
public void run() {
Message message = Message.obtain();
try {
//从网络下载图片
URL url = new URL(mUrl);//spec:请求路径
//获取连接操作
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5000);//连接超时时间
con.setReadTimeout(5000);//读取超时时间
InputStream inputStream = con.getInputStream();//获取服务器返回的数据
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
//将下载的图片保存到缓存文件中和内存中
lruCache.put(mUrl, bitmap);
setBitmapToLocal(mUrl, bitmap);
//通过Handler将数据传递给MenuPhotospager进行显示
message.what = MenuPhotosPager.SUCCESS;
message.obj = bitmap;
message.arg1=mPosition;
mHandler.sendMessage(message);
return;//通知线程池,线程已经使用完毕,可以回收
} catch (Exception e) {
e.printStackTrace();
//return;
}
message.what = MenuPhotosPager.FAIL;
mHandler.sendMessage(message);
}
}
/**
* 获取本地缓存的图片
* @param url
*/
private Bitmap getBitmapFromLocal(String url) {
try {
File file = new File(cacheDir, MD5Util.Md5(url).substring(10));
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
//将图片保存内存中
lruCache.put(url, bitmap);
return bitmap;
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
/**
* 保存图片到本地文件中
*/
public void setBitmapToLocal(String url,Bitmap bitmap){
try {
File file = new File(cacheDir, MD5Util.Md5(url).substring(10));
FileOutputStream stream = new FileOutputStream(file);
//format : 图片的格式
//quality : 图片的质量
//stream : 写入流
//PNG : 图片质量不可变
bitmap.compress(CompressFormat.JPEG, 100, stream);//设置图片的格式、质量,并保存到相应的文件中
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
其实Glide和Picasso差不多,但是Glide比Picasso更易用
Glide和Picasso
Glide.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
public class GlideConfiguration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
同时在AndroidManifest.xml中将GlideModule定义为meta-data
"com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
android:value="GlideModule"/>
我比较喜欢使用Glide,毕竟速度快,占用内存少,但是如果少量图片,并且想要高质量的图片,可以使用Picasso,当然萝卜白菜各有所爱,就看个人喜好了
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//创建默认的ImageLoader配置参数
ImageLoaderConfiguration configuration = ImageLoaderConfiguration
.createDefault(this);
//Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(configuration);
}
}
//显示图片的配置
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
ImageLoader.getInstance().displayImage(imageUrl, mImageView, options);
imageLoader.displayImage(imageUrl, mImageView, options, new SimpleImageLoadingListener(), new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current,
int total) {
}
});