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

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

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

package cindy.android.util;import android.os.Handler;import android.os.Looper;import android.os.Message;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 LooperThread extends 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){};     }


package cindy.android.util;import java.io.DataInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.ref.SoftReference;import java.net.URL;import java.util.HashMap;import cindy.android.debug.DebugUtil;import android.graphics.drawable.Drawable;import android.os.Environment;import android.os.Handler;public class SyncImageLoader {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>>();RunInOtherThread runInOutherThread;public SyncImageLoader() {super();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) {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() {@Overridepublic void run() {if (!mAllowLoad) {synchronized (lock) {try {DebugUtil.debug("wait start.....");lock.wait();DebugUtil.debug("wait end.....");} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}if (mAllowLoad && firstLoad) {loadImage(mImageUrl, mt, mListener);}if (mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit) {loadImage(mImageUrl, mt, mListener);}}});}private void loadImage(final String mImageUrl, final Integer mt,final OnImageLoadListener mListener) {if (imageCache.containsKey(mImageUrl)) {SoftReference<Drawable> softReference = imageCache.get(mImageUrl);final Drawable d = softReference.get();if (d != null) {handler.post(new Runnable() {@Overridepublic void run() {if (mAllowLoad) {mListener.onImageLoad(mt, d);}}});return;}}try {final Drawable d = loadImageFromUrl(mImageUrl);if (d != null) {imageCache.put(mImageUrl, new SoftReference<Drawable>(d));}handler.post(new Runnable() {@Overridepublic void run() {if (mAllowLoad) {mListener.onImageLoad(mt, d);}}});} catch (IOException e) {handler.post(new Runnable() {@Overridepublic 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()+ "/TestSyncListView/" + MD5.getMD5(url));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();Drawable d = Drawable.createFromStream(i, "src");return loadImageFromUrl(url);} else {URL m = new URL(url);InputStream i = (InputStream) m.getContent();Drawable d = Drawable.createFromStream(i, "src");return d;}}}

更多相关文章

  1. Activity的构成
  2. Android中TextView中添加的文本上下两行又重叠
  3. Android常用的一些服务demo源码
  4. Android新的网络请求框架volley源码解释及示例
  5. android init.rc 到底在哪里?
  6. Android中Fragment碎片解析
  7. 框架和流程——OkHttp 源码详解(一)
  8. 在Android中使用AspectJ进行切面编程的简易步骤
  9. Camera的学习,图片的保存(两种),获取手机图片以及图片信息修改(小的图

随机推荐

  1. Android路线图
  2. 如何从Android so中提取URL
  3. Android Accessibility(辅助功能) 安全相
  4. 波音787 Dreamliner娱乐系统将选择Androi
  5. Android中通过WebView控件实现与JavaScri
  6. Android Studio 单刷《第一行代码》系列
  7. Android生成签名文件并用其对apk文件进行
  8. Android模拟神器――Genymotion
  9. Android辅助功能AccessibilityService与
  10. 如何在MainActivity中使用ReactApplicati