又优化了一下Android ListView 异步加载图片(续)

之前发表过一篇文章: 又优化了一下 Android ListView 异步加载图片 
大家反应还行,不过普遍爆出new Thread太多会导致性能和资源浪费的问题,我想了一下的确如此,有人说用AsyncTask会更好点,因为实现的原理是线程池,肯定是比new Thread强,这个我也没有考证,后来根据自己的一套做了一些修改,只是一直没发出来,然后有些同学线下又找我要修改后的源码,我就索性把我修改的发出来给大家分享一下。

其实改动不大,就是把之前的new Thread改成了 Handler Looper Thread的模式,这样在第一次滑动的时候就进入了wait状态,又因为handler里面的runnable是队列执行的,所以handler一直在添加的runnable也在等待,这样就避免了多次new thread的问题,从头到尾就只有一个thread,别的不多说,看修改后的代码。

源码我就不上传了,就添加了一个类,修改了一个类:

Runinotherthread代码   收藏代码
  1. package cindy.android.util;  
  2.   
  3. import android.os.Handler;  
  4. import android.os.Looper;  
  5. import android.os.Message;  
  6.   
  7.   
  8. public class RunInOtherThread {  
  9.     private static final String LOG_TAG = "RunInOtherThread";  
  10.       
  11.     private LooperThread localThread = new LooperThread();  
  12.       
  13.     private boolean isRunning = true;  
  14.   
  15.     public Handler getHandler(){  
  16.         return localThread.getHandler();  
  17.     }  
  18.       
  19.     private class LooperThread extends Thread {  
  20.         private Handler mHandler;  
  21.   
  22.         public void run() {  
  23.             Looper.prepare();  
  24.             mHandler = new Handler() {  
  25.                 public void handleMessage(Message msg) {  
  26.                     onReceiveMessage(msg.what);  
  27.                 }  
  28.             };  
  29.             Looper.loop();  
  30.         }  
  31.           
  32.         Handler getHandler(){  
  33.             return mHandler;  
  34.         }  
  35.      
  36.     }  
  37.       
  38.     public void start(){  
  39.         localThread.start();  
  40.     }  
  41.       
  42.     public void quit(){  
  43.         localThread.getHandler().getLooper().quit();  
  44.     }  
  45.       
  46.     public void sendMessage(int what){  
  47.         getHandler().sendEmptyMessage(what);  
  48.     }  
  49.       
  50.     public Thread getThread(){  
  51.         return localThread;  
  52.     }  
  53.       
  54.     public void onReceiveMessage(int what){};  
  55.        
  56. }  
 

Syncimageloader代码   收藏代码
  1. package cindy.android.util;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.lang.ref.SoftReference;  
  10. import java.net.URL;  
  11. import java.util.HashMap;  
  12.   
  13. import cindy.android.debug.DebugUtil;  
  14.   
  15. import android.graphics.drawable.Drawable;  
  16. import android.os.Environment;  
  17. import android.os.Handler;  
  18.   
  19. public class SyncImageLoader {  
  20.   
  21.     private Object lock = new Object();  
  22.   
  23.     private boolean mAllowLoad = true;  
  24.   
  25.     private boolean firstLoad = true;  
  26.   
  27.     private int mStartLoadLimit = 0;  
  28.   
  29.     private int mStopLoadLimit = 0;  
  30.   
  31.     final Handler handler = new Handler();  
  32.   
  33.     private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();  
  34.   
  35.     RunInOtherThread runInOutherThread;  
  36.   
  37.     public SyncImageLoader() {  
  38.         super();  
  39.         runInOutherThread = new RunInOtherThread();  
  40.         runInOutherThread.start();  
  41.     }  
  42.   
  43.     public interface OnImageLoadListener {  
  44.         public void onImageLoad(Integer t, Drawable drawable);  
  45.   
  46.         public void onError(Integer t);  
  47.     }  
  48.   
  49.     public void setLoadLimit(int startLoadLimit, int stopLoadLimit) {  
  50.         if (startLoadLimit > stopLoadLimit) {  
  51.             return;  
  52.         }  
  53.         mStartLoadLimit = startLoadLimit;  
  54.         mStopLoadLimit = stopLoadLimit;  
  55.     }  
  56.   
  57.     public void restore() {  
  58.         mAllowLoad = true;  
  59.         firstLoad = true;  
  60.     }  
  61.   
  62.     public void lock() {  
  63.         mAllowLoad = false;  
  64.         firstLoad = false;  
  65.     }  
  66.   
  67.     public void unlock() {  
  68.         mAllowLoad = true;  
  69.         synchronized (lock) {  
  70.             lock.notifyAll();  
  71.         }  
  72.     }  
  73.   
  74.     public void loadImage(Integer t, String imageUrl,  
  75.             OnImageLoadListener listener) {  
  76.         final OnImageLoadListener mListener = listener;  
  77.         final String mImageUrl = imageUrl;  
  78.         final Integer mt = t;  
  79.           
  80.         runInOutherThread.getHandler().post(new Runnable() {  
  81.   
  82.             @Override  
  83.             public void run() {  
  84.                 if (!mAllowLoad) {  
  85.                     synchronized (lock) {  
  86.                         try {  
  87.                             DebugUtil.debug("wait start.....");  
  88.                             lock.wait();  
  89.                             DebugUtil.debug("wait end.....");  
  90.                         } catch (InterruptedException e) {  
  91.                             // TODO Auto-generated catch block  
  92.                             e.printStackTrace();  
  93.                         }  
  94.                     }  
  95.                 }  
  96.                   
  97.                 if (mAllowLoad && firstLoad) {  
  98.                     loadImage(mImageUrl, mt, mListener);  
  99.                 }  
  100.   
  101.                 if (mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit) {  
  102.                     loadImage(mImageUrl, mt, mListener);  
  103.                 }  
  104.             }  
  105.   
  106.         });  
  107.     }  
  108.       
  109.     private void loadImage(final String mImageUrl, final Integer mt,  
  110.             final OnImageLoadListener mListener) {  
  111.   
  112.         if (imageCache.containsKey(mImageUrl)) {  
  113.             SoftReference<Drawable> softReference = imageCache.get(mImageUrl);  
  114.             final Drawable d = softReference.get();  
  115.             if (d != null) {  
  116.                 handler.post(new Runnable() {  
  117.                     @Override  
  118.                     public void run() {  
  119.                         if (mAllowLoad) {  
  120.                             mListener.onImageLoad(mt, d);  
  121.                         }  
  122.                     }  
  123.                 });  
  124.                 return;  
  125.             }  
  126.         }  
  127.         try {  
  128.             final Drawable d = loadImageFromUrl(mImageUrl);  
  129.             if (d != null) {  
  130.                 imageCache.put(mImageUrl, new SoftReference<Drawable>(d));  
  131.             }  
  132.             handler.post(new Runnable() {  
  133.                 @Override  
  134.                 public void run() {  
  135.                     if (mAllowLoad) {  
  136.                         mListener.onImageLoad(mt, d);  
  137.                     }  
  138.                 }  
  139.             });  
  140.         } catch (IOException e) {  
  141.             handler.post(new Runnable() {  
  142.                 @Override  
  143.                 public void run() {  
  144.                     mListener.onError(mt);  
  145.                 }  
  146.             });  
  147.             e.printStackTrace();  
  148.         }  
  149.     }  
  150.   
  151.     public static Drawable loadImageFromUrl(String url) throws IOException {  
  152.         //DebugUtil.debug(url);  
  153.         if (Environment.getExternalStorageState().equals(  
  154.                 Environment.MEDIA_MOUNTED)) {  
  155.             File f = new File(Environment.getExternalStorageDirectory()  
  156.                     + "/TestSyncListView/" + MD5.getMD5(url));  
  157.             if (f.exists()) {  
  158.                 FileInputStream fis = new FileInputStream(f);  
  159.                 Drawable d = Drawable.createFromStream(fis, "src");  
  160.                 return d;  
  161.             }  
  162.             URL m = new URL(url);  
  163.             InputStream i = (InputStream) m.getContent();  
  164.             DataInputStream in = new DataInputStream(i);  
  165.             FileOutputStream out = new FileOutputStream(f);  
  166.             byte[] buffer = new byte[1024];  
  167.             int byteread = 0;  
  168.             while ((byteread = in.read(buffer)) != -1) {  
  169.                 out.write(buffer, 0, byteread);  
  170.             }  
  171.             in.close();  
  172.             out.close();  
  173.             Drawable d = Drawable.createFromStream(i, "src");  
  174.             return loadImageFromUrl(url);  
  175.         } else {  
  176.             URL m = new URL(url);  
  177.             InputStream i = (InputStream) m.getContent();  
  178.             Drawable d = Drawable.createFromStream(i, "src");  
  179.             return d;  
  180.         }  
  181.   
  182.     }  
  183. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值