现在的位置: 首页 > 综合 > 正文

android图片异步加载

2018年05月16日 ⁄ 综合 ⁄ 共 5362字 ⁄ 字号 评论关闭

来自于:

http://www.iteye.com/topic/1127914

在此,感谢作者.

 

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

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

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

Runinotherthread代码  :

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){};
    
}

 

 

 

Syncimageloader代码  :
 

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() {

   @Override
   public void run() {
    if (!mAllowLoad) {
     synchronized (lock) {
      try {
       DebugUtil.debug("wait start.....");
       lock.wait();
       DebugUtil.debug("wait end.....");
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.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() {
     @Override
     public 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() {
    @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()
     + "/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;
  }

 }
}

 

抱歉!评论已关闭.