Bitmap加载于imageView的一些坑

来源:互联网 发布:mac怎么设置开机密码 编辑:程序博客网 时间:2024/05/17 00:18

1.imageView加载的Bitmap,如果想要设置相同的大小,就是bitmap可以刚好填充好整个imageView。

1.裁剪bitmap,获取imageview的宽高,然后调用bitmap.getScaledBitmap来实现,这样在加载大图时可能会OOM。不建议!!!!

2.在代码中设置imageView的宽高,然后imageView的xml设置

        android:adjustViewBounds="true"        android:scaleType="fitXY"
这样就可以让图片自适应宽度和高度,推荐这样!!


2.像listView,Viewpager这种加载很多大图的文件,最好使用图片的缓存加载,图片的加载方式为:

1.先检查内存中是否有该图片,有的话就加载,因为内存中加载最快。

2.再检查本地文件中是否有该图片,图片为第二部。

3.最后从网上下载图片。

MemoryCache类:

public class MemoryCache {    private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());        public Bitmap get(String id){        if(!cache.containsKey(id))            return null;        SoftReference<Bitmap> ref=cache.get(id);        return ref.get();    }        public void put(String id, Bitmap bitmap){        cache.put(id, new SoftReference<Bitmap>(bitmap));    }    public void clear() {        cache.clear();    }}

FileCache类:

public class FileCache {        private File cacheDir;        public FileCache(Context context){        //Find the dir to save cached images        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"QingTianBiZhi");        else            cacheDir=context.getCacheDir();        if(!cacheDir.exists())            cacheDir.mkdirs();    }        public File getFile(String url){        //I identify images by hashcode. Not a perfect solution, good for the demo.        String filename=String.valueOf(url.hashCode())+".jpg";        //Another possible solution (thanks to grantland)        //String filename = URLEncoder.encode(url);        File f = new File(cacheDir, filename);        return f;            }    public String getFilePath(String url){        String filename= cacheDir.getAbsolutePath()+"/" + String.valueOf(url.hashCode())+".jpg";        return filename;    }    public void clear(){        File[] files=cacheDir.listFiles();        if(files==null)            return;        for(File f:files)            f.delete();    }}

载入图片的时候也要考虑开启线程,而不要在主线程中去网上download图片。

imageLoader类:

public class ImageLoader {    MemoryCache memoryCache=new MemoryCache();    FileCache fileCache;    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());    ExecutorService executorService;public ImageLoader(Context context,int type){        fileCache=new FileCache(context);        executorService=Executors.newFixedThreadPool(5);    }private void queuePhoto(String url, ImageView imageView)    {        PhotoToLoad p=new PhotoToLoad(url, imageView);        executorService.submit(new PhotosLoader(p));    }private class PhotoToLoad    {        public String url;        public ImageView imageView;        public PhotoToLoad(String u, ImageView i){            url=u;            imageView=i;        }    }    class PhotosLoader implements Runnable {        PhotoToLoad photoToLoad;        PhotosLoader(PhotoToLoad photoToLoad){            this.photoToLoad=photoToLoad;        }        @Override        public void run() {            if(imageViewReused(photoToLoad))                return;            Bitmap bmp=getBitmap(photoToLoad.url);            memoryCache.put(photoToLoad.url, bmp);            if(imageViewReused(photoToLoad))                return;            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);            Activity a=(Activity)photoToLoad.imageView.getContext();            a.runOnUiThread(bd);        }    }    boolean imageViewReused(PhotoToLoad photoToLoad){        String tag=imageViews.get(photoToLoad.imageView);        if(tag==null || !tag.equals(photoToLoad.url))            return true;        return false;    }    //Used to display bitmap in the UI thread    class BitmapDisplayer implements Runnable    {        Bitmap bitmap;        PhotoToLoad photoToLoad;        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}        public void run()        {            if(imageViewReused(photoToLoad))                return;            if(bitmap!=null){//                bitmap = getScaledBitmap(bitmap,photoToLoad.imageView);                photoToLoad.imageView.setImageBitmap(bitmap);            }            else                // photoToLoad.imageView.setImageResource(stub_id);                photoToLoad.imageView.setBackgroundColor(Color.WHITE);        }    }    public void clearCache() {        memoryCache.clear();        fileCache.clear();    }

imageLoader的getBitmap方法:

public Bitmap getBitmap(String url)    {        File f=fileCache.getFile(url);        //from SD cache       // Bitmap b = decodeFile(f);        Bitmap b=getBitmapByPath(fileCache.getFilePath(url));        if(b!=null)            return b;        //from web        try {            URL imageUrl = new URL(url);            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();            conn.setConnectTimeout(30000);            conn.setReadTimeout(30000);            conn.setInstanceFollowRedirects(true);            InputStream is=conn.getInputStream();            OutputStream os=null;            try{                os= new FileOutputStream(f);                Utils.CopyStream(is, os);            }catch (Exception ex){                ex.printStackTrace();            }finally{                os.close();            }            b=getBitmapByPath(fileCache.getFilePath(url));        } catch (Exception ex){            ex.printStackTrace();            b= null;        }        return b;    }    private Bitmap getBitmapByPath(String path){        Bitmap bitmap=null;        BitmapFactory.Options o2 = new BitmapFactory.Options();        o2.inPreferredConfig=Bitmap.Config.ARGB_4444;        int scale=1;        o2.inSampleSize=scale;        Bitmap result = null;        while(true){            try {                bitmap= BitmapFactory.decodeFile(path,o2);                break;            }catch (OutOfMemoryError e){                scale *= 2;                o2.inSampleSize = scale;            }        }        return bitmap;    }


3.除了像第二步一样用线程任务去加载,还可以利用缓存来提升体验,比如如果ViewPager的预览图是已经压缩过的小图,希望点击预览图查看大图。

可以在初始化时传递预览图的url来解析图片,再在PagerAdatper的 instantiateItem 中以完整大图的url显示一次,这样就会有延迟加载的效果。


0 0
原创粉丝点击