android使用LruCache对listview加载图片时候优化处理-阿里云开发者社区

开发者社区> code_xzh> 正文

android使用LruCache对listview加载图片时候优化处理

简介: 注意:LruCache是有版本限制的,低版本的sdk需要在libs文件夹添加相应的support-4v文件。 本文改造的大部分是参考http://www.iteye.com/topic/1118828,感谢。 不废话直接上工程代码,内有关键注释,项目就不上传了,自己对照着上面网址改呗。 首先是Application文件,负责创建图片存储文件夹: public c
+关注继续查看

注意:LruCache是有版本限制的,低版本的sdk需要在libs文件夹添加相应的support-4v文件。
本文改造的大部分是参考http://www.iteye.com/topic/1118828,感谢。
不废话直接上工程代码,内有关键注释,项目就不上传了,自己对照着上面网址改呗。


首先是Application文件,负责创建图片存储文件夹:

复制代码
public class MyApp extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        File f = new File(Environment.getExternalStorageDirectory()+"/TestSyncListView/pic/");
        if (!f.exists()) {
            f.mkdirs();
        }
    }
}
复制代码


图像读取工具类:

?
public class SyncImageLoaderUtil {
    private Object lock = new Object(); 
       
    private boolean mAllowLoad = true
   
    private boolean firstLoad = true
   
    private int mStartLoadLimit = 0
   
    private int mStopLoadLimit = 0
   
    final Handler handler = new Handler(); 
   
//    private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>(); 
   
    private LruCache<String,Bitmap> mMemoryCache;
     
    RunInOtherThread runInOutherThread; 
   
    public SyncImageLoaderUtil(Context context) { 
        super(); 
         
        int memClass = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
        int cacheSize = 1024 *1024 *memClass / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                // TODO Auto-generated method stub
                return value.getRowBytes();
            }
        };
         
        runInOutherThread = new RunInOtherThread(); 
        runInOutherThread.start(); 
    
   
    public interface OnImageLoadListener { 
        public void onImageLoad(Integer t, Drawable drawable); 
   
        public void onError(Integer t); 
    
   
    public void setLoadLimit(int startLoadLimit,int stopLoadLimit) { 
        if (startLoadLimit > stopLoadLimit) { 
//          LogUtil.i("test", startLoadLimit+"--错误---"+stopLoadLimit);
            return
        
        mStartLoadLimit = startLoadLimit; 
        mStopLoadLimit = stopLoadLimit; 
    
   
    public void restore() { 
        mAllowLoad = true
        firstLoad = true
    
   
    public void lock() { 
        mAllowLoad = false
        firstLoad = false
    
   
    public void unlock() { 
        mAllowLoad = true
        synchronized (lock) { 
            lock.notifyAll(); 
        
    
   
    public void loadImage(Integer t, String imageUrl, 
            OnImageLoadListener listener) { 
        final OnImageLoadListener mListener = listener; 
        final String mImageUrl = imageUrl; 
        final Integer mt = t; 
           
        runInOutherThread.getHandler().post(new Runnable() { 
   
            @Override 
            public void run() { 
                if (!mAllowLoad) { 
                    synchronized (lock) { 
                        try 
                            lock.wait(); 
                        }catch (InterruptedException e) { 
                            // TODO Auto-generated catch block 
                            e.printStackTrace(); 
                        
                    
                
                   
                if (mAllowLoad && firstLoad) { 
                    loadImage(mImageUrl, mt, mListener); 
                
   
//                LogUtil.e("test", "原始开始:"+mStartLoadLimit+"原始当前位置:"+mt+"原始结束:"+mStopLoadLimit);
                if (mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit) { 
//                  LogUtil.e("test", "开始:"+mStartLoadLimit+"当前位置:"+mt+"结束:"+mStopLoadLimit);
                    loadImage(mImageUrl, mt, mListener);
                
            
   
        }); 
    
       
    private void loadImage(final String mImageUrl, final Integer mt, 
            final OnImageLoadListener mListener) { 
   
        if (mImageUrl!=null && mMemoryCache.get(mImageUrl)!=null) { 
//            SoftReference<Drawable> softReference = imageCache.get(mImageUrl); 
            final Drawable d = new BitmapDrawable(mMemoryCache.get(mImageUrl)); 
//            LogUtil.d("ppp", "drawable:"+d);
            if (d != null) { 
                handler.post(new Runnable() { 
                    @Override 
                    public void run() { 
                        if (mAllowLoad) { 
                            mListener.onImageLoad(mt, d); 
                        
                    
                }); 
                return
            
        
        try 
            final Drawable d = loadImageFromUrl(mImageUrl); 
            if (d != null) { 
                mMemoryCache.put(mImageUrl, ((BitmapDrawable)d).getBitmap());
            
            handler.post(new Runnable() { 
                @Override 
                public void run() { 
                    if (mAllowLoad) { 
                        mListener.onImageLoad(mt, d); 
                    
                
            }); 
        }catch (IOException e) { 
            handler.post(new Runnable() { 
                @Override 
                public void run() { 
                    mListener.onError(mt); 
                
            }); 
            e.printStackTrace(); 
        
    
   
    public static Drawable loadImageFromUrl(String url) throws IOException { 
        //DebugUtil.debug(url); 
        if (Environment.getExternalStorageState().equals( 
                Environment.MEDIA_MOUNTED)) { 
            File f = new File(Environment.getExternalStorageDirectory() 
                    +"/Weiyu/pic/" + MD5Util.getMD5(url.getBytes())); 
            if (f.exists()) { 
                FileInputStream fis = new FileInputStream(f); 
                Drawable d = Drawable.createFromStream(fis, "src"); 
                return d; 
            
            URL m = new URL(url); 
            InputStream i = (InputStream) m.getContent(); 
            DataInputStream in = new DataInputStream(i); 
            FileOutputStream out = new FileOutputStream(f); 
            byte[] buffer = new byte[1024]; 
            int byteread = 0
            while ((byteread = in.read(buffer)) != -1) { 
                out.write(buffer,0, byteread); 
            
            
            in.close(); 
            out.close();
            return loadImageFromUrl(url); 
        }else 
            URL m = new URL(url); 
            InputStream i = (InputStream) m.getContent(); 
            Drawable d = Drawable.createFromStream(i, "src"); 
            return d; 
        
   
    
}

  
线程辅助类:

?
public class RunInOtherThread {
    private static final String LOG_TAG = "RunInOtherThread"
     
    private LooperThread localThread = new LooperThread(); 
       
    private boolean isRunning = true
   
    public Handler getHandler(){ 
        return localThread.getHandler(); 
    
       
    private class LooperThreadextends Thread { 
        private Handler mHandler; 
   
        public void run() { 
            Looper.prepare(); 
            mHandler = new Handler() { 
                public void handleMessage(Message msg) { 
                    onReceiveMessage(msg.what); 
                
            }; 
            Looper.loop(); 
        
           
        Handler getHandler(){ 
            return mHandler; 
        
      
    
       
    public void start(){ 
        localThread.start(); 
    
       
    public void quit(){ 
        localThread.getHandler().getLooper().quit(); 
    
       
    public void sendMessage(int what){ 
        getHandler().sendEmptyMessage(what); 
    
       
    public Thread getThread(){ 
        return localThread; 
    
       
    public void onReceiveMessage(int what){};
}

  
使用类:

?
// 实例化工具类
SyncImageLoaderUtil syncImageLoader = new SyncImageLoaderUtil(mContext);
 
syncImageLoader.loadImage(position, model.mPic, imageLoadListener);//应用接口:参数一是加载图片的位置;参数二是加载的ImageView;参数三是回调接口
 
// map保存的键是位置,值是listview对应位置的布局
HashMap map = new HashMap();
map.put(position, convertView);
 
SyncImageLoaderUtil.OnImageLoadListener imageLoadListener = new SyncImageLoaderUtil.OnImageLoadListener() {
 
        @Override
        public void onImageLoad(Integer t, Drawable drawable) {
            View view = (View) map.get(t);
            if (view != null) {
                ImageView iv = (ImageView) view.findViewById(R.id.image);
                iv.setBackgroundDrawable(drawable);
            }
        }
 
        @Override
        public void onError(Integer t) {
                        // 图片加载失败
                       // 取得listview对应的位置的行的内容布局
                    MusicModel model = (MusicModel) getItem(t);
            View view = mListView.findViewWithTag(model);
            if (view != null) {
                ImageView iv = (ImageView) view.findViewById(R.id.image);
                iv.setBackgroundResource(R.drawable.img_pic);
            }
        }
 
    };
 
 
// 实现类而且需要实现OnScrollListener接口
public void loadImage() {
                // 不要在这里使用listview的getFirstVisiblePosition方法,位置不准
        if (end >= getCount()) {
            end = getCount() - 1;
        }
        syncImageLoader.setLoadLimit(start, end);
        syncImageLoader.unlock();
    }
 
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub
        if (lodingView) {
            switch (scrollState) {
            case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                syncImageLoader.lock();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
 
                loadImage();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                syncImageLoader.lock();
                break;
            default:
                break;
            }
        }
    }
 
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount,int totalItemCount) {
        // 在这里取得的位置较准确,不过也会出现特殊的奇疤机型是不行的
                // start与end是定义的变量
        start = firstVisibleItem;
        end = firstVisibleItem + visibleItemCount;
        if (firstVisibleItem != 0) {
                        // lodingView是控制变量,用来控制第一次进来视图加载读取图片
            lodingView = true;
        }else {
            lodingView = false;
            loadImage();
        }
    }

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[Android]使用RecyclerView替代ListView(三)
以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4268097.html    这次来使用RecyclerView实现PinnedListView的效果,效果很常见: 开发的代码建立在上一篇([Android]使用RecyclerView替代ListView(二):http://www.cnblogs.com/tiantianbyconan/p/4242541.html)基础之上。
858 0
[Android]使用RecyclerView替代ListView(一)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4232560.html   RecyclerView是一个比ListView更灵活的一个控件,以后可以直接抛弃ListView了。
728 0
Android Studio 使用ViewPager + Fragment实现滑动菜单Tab效果 --简易版
描述:         之前有做过一个记账本APP,拿来练手的,做的很简单,是用Eclipse开发的;         最近想把这个APP重新完善一下,添加了一些新的功能,并选用Android Studio来开发;         APP已经完善了一部分,现在就想把已经做好的功能整理一下,记录下来。
2542 0
[Android]使用RecyclerView替代ListView(四:SeizeRecyclerView)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6641794.html [Android]使用RecyclerView替代ListView(四:SeizeRecyclerView) 在RecyclerView的...
890 0
在使用蓝牙接口,遇到IOS下正常,Android下不正常的简易处理方法
如果遇到以上的情况怎么办,先确定下在调试的时候是否打开了调试面板, 如果有打开请关闭调试面板看是否还有问题,目前在安卓上打开调试面板是会有影响到蓝牙接口的使用,从之前遇到过这些问题的统计中也确实是因为这个原因
240 0
SAP LSMW 导入OPEN PO 单据时候’税码’字段的处理
SAP LSMW Standard Batch (Direct) Input 方式制作的LSMW工具导入OPEN PO 单据时候’税码’字段的处理 如下的Open PO 批量导入LSMW工具,   ...
1087 0
[Android]ListView的Adapter.getView()方法中延迟加载图片的优化
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4139998.html   举个例子吧,以好友列表为例 ListView中每个Item表示一个好友,每个好友中都有一个头像,需要从服务端加载到本地,然后显示在item中。
757 0
+关注
code_xzh
对前端移动客户端技术比较擅长。著有《React Native移动开发实战》和《Kotlin入门与实战》和《Weex跨平台实战》,《React Native移动开发进阶》即将出版,正在努力完成《Flutter跨平台开发实战》
736
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载