转载:Android实现ListView异步加载图片
2010-12-29 18:08
766 查看
ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,不用让用户等待下去,下面就说实现方法,先贴上主方法的代码:
package
cn.wangmeng.test;
import
java.io.IOException;
import
java.io.InputStream;
import
java.lang.ref.SoftReference;
import
java.net.MalformedURLException;
import
java.net.URL;
import
java.util.HashMap;
import
android.graphics.drawable.Drawable;
import
android.os.Handler;
import
android.os.Message;
public
class
AsyncImageLoader {
private
HashMap
<
String, SoftReference
<
Drawable
>>
imageCache;
public
AsyncImageLoader() {
imageCache
=
new
HashMap
<
String, SoftReference
<
Drawable
>>
();
}
public
Drawable loadDrawable(
final
String imageUrl,
final
ImageCallback imageCallback) {
if
(imageCache.containsKey(imageUrl)) {
SoftReference
<
Drawable
>
softReference
=
imageCache.get(imageUrl);
Drawable drawable
=
softReference.get();
if
(drawable
!=
null
) {
return
drawable;
}
}
final
Handler handler
=
new
Handler() {
public
void
handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
new
Thread() {
@Override
public
void
run() {
Drawable drawable
=
loadImageFromUrl(imageUrl);
imageCache.put(imageUrl,
new
SoftReference
<
Drawable
>
(drawable));
Message message
=
handler.obtainMessage(
0
, drawable);
handler.sendMessage(message);
}
}.start();
return
null
;
}
public
static
Drawable loadImageFromUrl(String url) {
URL m;
InputStream i
=
null
;
try
{
m
=
new
URL(url);
i
=
(InputStream) m.getContent();
}
catch
(MalformedURLException e1) {
e1.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
Drawable d
=
Drawable.createFromStream(i,
"
src
"
);
return
d;
}
public
interface
ImageCallback {
public
void
imageLoaded(Drawable imageDrawable, String imageUrl);
}
}
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。
ViewCache是辅助获取adapter的子元素布局
package
cn.wangmeng.test;
import
java.util.List;
import
cn.wangmeng.test.AsyncImageLoader.ImageCallback;
import
android.app.Activity;
import
android.graphics.drawable.Drawable;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.ArrayAdapter;
import
android.widget.ImageView;
import
android.widget.ListView;
import
android.widget.TextView;
public
class
ImageAndTextListAdapter
extends
ArrayAdapter
<
ImageAndText
>
{
private
ListView listView;
private
AsyncImageLoader asyncImageLoader;
public
ImageAndTextListAdapter(Activity activity, List
<
ImageAndText
>
imageAndTexts, ListView listView) {
super
(activity,
0
, imageAndTexts);
this
.listView
=
listView;
asyncImageLoader
=
new
AsyncImageLoader();
}
public
View getView(
int
position, View convertView, ViewGroup parent) {
Activity activity
=
(Activity) getContext();
//
Inflate the views from XML
View rowView
=
convertView;
ViewCache viewCache;
if
(rowView
==
null
) {
LayoutInflater inflater
=
activity.getLayoutInflater();
rowView
=
inflater.inflate(R.layout.image_and_text_row,
null
);
viewCache
=
new
ViewCache(rowView);
rowView.setTag(viewCache);
}
else
{
viewCache
=
(ViewCache) rowView.getTag();
}
ImageAndText imageAndText
=
getItem(position);
//
Load the image and set it on the ImageView
String imageUrl
=
imageAndText.getImageUrl();
ImageView imageView
=
viewCache.getImageView();
imageView.setTag(imageUrl);
Drawable cachedImage
=
asyncImageLoader.loadDrawable(imageUrl,
new
ImageCallback() {
public
void
imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag
=
(ImageView) listView.findViewWithTag(imageUrl);
if
(imageViewByTag
!=
null
) {
imageViewByTag.setImageDrawable(imageDrawable);
}
}
});
if
(cachedImage
==
null
) {
imageView.setImageResource(R.drawable.default_image);
}
else
{
imageView.setImageDrawable(cachedImage);
}
//
Set the text on the TextView
TextView textView
=
viewCache.getTextView();
textView.setText(imageAndText.getText());
return
rowView;
}
}
ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。
方法二:
package com.android.dieke.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
/**
* This helper class download images from the Internet and binds those with the
* provided ImageView.
* <p>
* It requires the INTERNET permission, which should be added to your
* application's manifest * file.
* </p>
* * * A local cache of downloaded images is maintained internally to improve
* performance.
*/
public class ImageDownloaderTask {
private static final String LOG_TAG = "ImageDowloader";
public enum Mode {
NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT
}
private Mode mode = Mode.NO_ASYNC_TASK;
public Bitmap download(String url, ImageView imageview) {
resetPurgeTimer();
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap == null) {
forceDownload(url, imageview);
} else {
cancelPotentialDownload(url, imageview);
imageview.setImageBitmap(bitmap);
}
return bitmap;
}
private void forceDownload(String url, ImageView imageview) {
if (url == null) {
imageview.setImageDrawable(null);
return;
}
if (cancelPotentialDownload(url, imageview)) {
switch (mode) {
case NO_ASYNC_TASK:
Bitmap bitmap = downloadBitmap(url);
addBitmapToCache(url, bitmap);
imageview.setImageBitmap(bitmap);
break;
case NO_DOWNLOADED_DRAWABLE:
imageview.setMinimumHeight(100);
BitmapDownloaderTask task = new BitmapDownloaderTask(imageview);
task.execute(url);
break;
case CORRECT:
task = new BitmapDownloaderTask(imageview);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(
task);
imageview.setImageDrawable(downloadedDrawable);
imageview.setMinimumHeight(156);
task.execute(url);
break;
}
}
}
private static boolean cancelPotentialDownload(String url,
ImageView imageview) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageview);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
private static BitmapDownloaderTask getBitmapDownloaderTask(
ImageView imageview) {
if (imageview != null) {
Drawable drawable = imageview.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
Bitmap downloadBitmap(String url) {
final int IO_BUFFER_SIZE = 4 * 1024;
final HttpClient client = new DefaultHttpClient();
//: AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.v("ImageDownloader", "Error" + statusCode
+ "while restrieving bitmap from" + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
return BitmapFactory.decodeStream(new FlushedInputStream(
inputStream));
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (IOException e) {
getRequest.abort();
Log.v(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
} catch (IllegalStateException e) {
getRequest.abort();
Log.w(LOG_TAG, "Incorrect URL: " + url);
} catch (Exception e) {
getRequest.abort();
Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
} finally {
if ((client instanceof AndroidHttpClient)) {
((AndroidHttpClient) client).close();
}
}
return null;
}
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L)
break;
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageview) {
imageViewReference = new WeakReference<ImageView>(imageview);
}
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
url = params[0];
return downloadBitmap(url);
}
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
addBitmapToCache(url, bitmap);
if (imageViewReference != null) {
ImageView imageview = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageview);
if ((this == bitmapDownloaderTask) || (mode != Mode.CORRECT)) {
imageview.setImageBitmap(bitmap);
}
}
}
}
static class DownloadedDrawable extends ColorDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference = new WeakReference<BitmapDownloaderTask>(
bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
public void setMode(Mode mode) {
this.mode = mode;
clearCache();
}
private static final int HARD_CACHE_CAPACITY = 10;
private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds
private final HashMap<String, Bitmap> sHardBitmapCache = new LinkedHashMap<String, Bitmap>(
HARD_CACHE_CAPACITY / 2, 0.75f, true) {
@Override
protected boolean removeEldestEntry(
LinkedHashMap.Entry<String, Bitmap> eldest) {
if (size() > HARD_CACHE_CAPACITY) {
// Entries push-out of hard reference cache are transferred to
// soft reference cache
sSoftBitmapCache.put(eldest.getKey(),
new SoftReference<Bitmap>(eldest.getValue()));
return true;
} else
return false;
}
};
private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(
HARD_CACHE_CAPACITY / 2);
private final Handler purgeHandler = new Handler();
private final Runnable purger = new Runnable() {
public void run() {
clearCache();
}
};
private void addBitmapToCache(String url, Bitmap bitmap) {
if (bitmap != null) {
synchronized (sHardBitmapCache) {
sHardBitmapCache.put(url, bitmap);
}
}
}
private Bitmap getBitmapFromCache(String url) {
synchronized (sHardBitmapCache) {
final Bitmap bitmap = sHardBitmapCache.get(url);
if (bitmap != null) {
sHardBitmapCache.remove(url);
sHardBitmapCache.put(url, bitmap);
return bitmap;
}
}
SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
if (bitmapReference != null) {
final Bitmap bitmap = bitmapReference.get();
if (bitmap != null) {
return bitmap;
} else {
sSoftBitmapCache.remove(url);
}
}
return null;
}
public void clearCache() {
sHardBitmapCache.clear();
sSoftBitmapCache.clear();
}
private void resetPurgeTimer() {
purgeHandler.removeCallbacks(purger);
purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE);
}
}
方法三:
/*package com.android.dieke.util;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import com.dieke._class.FoodInfo;
import com.dieke.adapter.GridAllFoodAdapter;
public class ImageLoadTask extends AsyncTask<Void, Void, Void> {
private static final String TAG = ImageLoadTask.class.getSimpleName();
private GridAllFoodAdapter adapter;
public ImageLoadTask(Context context, GridAllFoodAdapter adapter) {
Log.v(TAG, "ImageLoadTask()");
this.adapter = adapter;
}
@Override
protected void onPreExecute() {
Log.v(TAG, "onPreExecute()");
}
@Override
protected Void doInBackground(Void... voids) {
Log.v(TAG, "doInBackground()");
for (int i = 0; i < adapter.getCount(); i++) {
FoodInfo bean = adapter.getItem(i);
try {
Log.d(TAG, bean.getFoodImgSrc());
URL url = new URL(bean.getFoodImgSrc());
Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());
Log.d(TAG, (bitmap == null) + "");
if (bitmap != null) {
bean.setBitmap(bitmap);
publishProgress();
}
} catch (Exception e) {
}
}
return null;
}
@Override
public void onProgressUpdate(Void... voids) {
Log.v(TAG, "onProgressUpdate()");
if (isCancelled())
return;
adapter.notifyDataSetChanged();
}
@Override
protected void onPostExecute(Void result) {
Log.v(TAG, "onPostExecute()");
}
}
*/
package
cn.wangmeng.test;
import
java.io.IOException;
import
java.io.InputStream;
import
java.lang.ref.SoftReference;
import
java.net.MalformedURLException;
import
java.net.URL;
import
java.util.HashMap;
import
android.graphics.drawable.Drawable;
import
android.os.Handler;
import
android.os.Message;
public
class
AsyncImageLoader {
private
HashMap
<
String, SoftReference
<
Drawable
>>
imageCache;
public
AsyncImageLoader() {
imageCache
=
new
HashMap
<
String, SoftReference
<
Drawable
>>
();
}
public
Drawable loadDrawable(
final
String imageUrl,
final
ImageCallback imageCallback) {
if
(imageCache.containsKey(imageUrl)) {
SoftReference
<
Drawable
>
softReference
=
imageCache.get(imageUrl);
Drawable drawable
=
softReference.get();
if
(drawable
!=
null
) {
return
drawable;
}
}
final
Handler handler
=
new
Handler() {
public
void
handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
new
Thread() {
@Override
public
void
run() {
Drawable drawable
=
loadImageFromUrl(imageUrl);
imageCache.put(imageUrl,
new
SoftReference
<
Drawable
>
(drawable));
Message message
=
handler.obtainMessage(
0
, drawable);
handler.sendMessage(message);
}
}.start();
return
null
;
}
public
static
Drawable loadImageFromUrl(String url) {
URL m;
InputStream i
=
null
;
try
{
m
=
new
URL(url);
i
=
(InputStream) m.getContent();
}
catch
(MalformedURLException e1) {
e1.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}
Drawable d
=
Drawable.createFromStream(i,
"
src
"
);
return
d;
}
public
interface
ImageCallback {
public
void
imageLoaded(Drawable imageDrawable, String imageUrl);
}
}
以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。
ViewCache是辅助获取adapter的子元素布局
package
cn.wangmeng.test;
import
java.util.List;
import
cn.wangmeng.test.AsyncImageLoader.ImageCallback;
import
android.app.Activity;
import
android.graphics.drawable.Drawable;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.ArrayAdapter;
import
android.widget.ImageView;
import
android.widget.ListView;
import
android.widget.TextView;
public
class
ImageAndTextListAdapter
extends
ArrayAdapter
<
ImageAndText
>
{
private
ListView listView;
private
AsyncImageLoader asyncImageLoader;
public
ImageAndTextListAdapter(Activity activity, List
<
ImageAndText
>
imageAndTexts, ListView listView) {
super
(activity,
0
, imageAndTexts);
this
.listView
=
listView;
asyncImageLoader
=
new
AsyncImageLoader();
}
public
View getView(
int
position, View convertView, ViewGroup parent) {
Activity activity
=
(Activity) getContext();
//
Inflate the views from XML
View rowView
=
convertView;
ViewCache viewCache;
if
(rowView
==
null
) {
LayoutInflater inflater
=
activity.getLayoutInflater();
rowView
=
inflater.inflate(R.layout.image_and_text_row,
null
);
viewCache
=
new
ViewCache(rowView);
rowView.setTag(viewCache);
}
else
{
viewCache
=
(ViewCache) rowView.getTag();
}
ImageAndText imageAndText
=
getItem(position);
//
Load the image and set it on the ImageView
String imageUrl
=
imageAndText.getImageUrl();
ImageView imageView
=
viewCache.getImageView();
imageView.setTag(imageUrl);
Drawable cachedImage
=
asyncImageLoader.loadDrawable(imageUrl,
new
ImageCallback() {
public
void
imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag
=
(ImageView) listView.findViewWithTag(imageUrl);
if
(imageViewByTag
!=
null
) {
imageViewByTag.setImageDrawable(imageDrawable);
}
}
});
if
(cachedImage
==
null
) {
imageView.setImageResource(R.drawable.default_image);
}
else
{
imageView.setImageDrawable(cachedImage);
}
//
Set the text on the TextView
TextView textView
=
viewCache.getTextView();
textView.setText(imageAndText.getText());
return
rowView;
}
}
ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应item,大家仔细阅读就知道了。
方法二:
package com.android.dieke.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
/**
* This helper class download images from the Internet and binds those with the
* provided ImageView.
* <p>
* It requires the INTERNET permission, which should be added to your
* application's manifest * file.
* </p>
* * * A local cache of downloaded images is maintained internally to improve
* performance.
*/
public class ImageDownloaderTask {
private static final String LOG_TAG = "ImageDowloader";
public enum Mode {
NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT
}
private Mode mode = Mode.NO_ASYNC_TASK;
public Bitmap download(String url, ImageView imageview) {
resetPurgeTimer();
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap == null) {
forceDownload(url, imageview);
} else {
cancelPotentialDownload(url, imageview);
imageview.setImageBitmap(bitmap);
}
return bitmap;
}
private void forceDownload(String url, ImageView imageview) {
if (url == null) {
imageview.setImageDrawable(null);
return;
}
if (cancelPotentialDownload(url, imageview)) {
switch (mode) {
case NO_ASYNC_TASK:
Bitmap bitmap = downloadBitmap(url);
addBitmapToCache(url, bitmap);
imageview.setImageBitmap(bitmap);
break;
case NO_DOWNLOADED_DRAWABLE:
imageview.setMinimumHeight(100);
BitmapDownloaderTask task = new BitmapDownloaderTask(imageview);
task.execute(url);
break;
case CORRECT:
task = new BitmapDownloaderTask(imageview);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(
task);
imageview.setImageDrawable(downloadedDrawable);
imageview.setMinimumHeight(156);
task.execute(url);
break;
}
}
}
private static boolean cancelPotentialDownload(String url,
ImageView imageview) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageview);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
private static BitmapDownloaderTask getBitmapDownloaderTask(
ImageView imageview) {
if (imageview != null) {
Drawable drawable = imageview.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
Bitmap downloadBitmap(String url) {
final int IO_BUFFER_SIZE = 4 * 1024;
final HttpClient client = new DefaultHttpClient();
//: AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.v("ImageDownloader", "Error" + statusCode
+ "while restrieving bitmap from" + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
return BitmapFactory.decodeStream(new FlushedInputStream(
inputStream));
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (IOException e) {
getRequest.abort();
Log.v(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
} catch (IllegalStateException e) {
getRequest.abort();
Log.w(LOG_TAG, "Incorrect URL: " + url);
} catch (Exception e) {
getRequest.abort();
Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
} finally {
if ((client instanceof AndroidHttpClient)) {
((AndroidHttpClient) client).close();
}
}
return null;
}
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L)
break;
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageview) {
imageViewReference = new WeakReference<ImageView>(imageview);
}
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
url = params[0];
return downloadBitmap(url);
}
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
addBitmapToCache(url, bitmap);
if (imageViewReference != null) {
ImageView imageview = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageview);
if ((this == bitmapDownloaderTask) || (mode != Mode.CORRECT)) {
imageview.setImageBitmap(bitmap);
}
}
}
}
static class DownloadedDrawable extends ColorDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference = new WeakReference<BitmapDownloaderTask>(
bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
public void setMode(Mode mode) {
this.mode = mode;
clearCache();
}
private static final int HARD_CACHE_CAPACITY = 10;
private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds
private final HashMap<String, Bitmap> sHardBitmapCache = new LinkedHashMap<String, Bitmap>(
HARD_CACHE_CAPACITY / 2, 0.75f, true) {
@Override
protected boolean removeEldestEntry(
LinkedHashMap.Entry<String, Bitmap> eldest) {
if (size() > HARD_CACHE_CAPACITY) {
// Entries push-out of hard reference cache are transferred to
// soft reference cache
sSoftBitmapCache.put(eldest.getKey(),
new SoftReference<Bitmap>(eldest.getValue()));
return true;
} else
return false;
}
};
private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(
HARD_CACHE_CAPACITY / 2);
private final Handler purgeHandler = new Handler();
private final Runnable purger = new Runnable() {
public void run() {
clearCache();
}
};
private void addBitmapToCache(String url, Bitmap bitmap) {
if (bitmap != null) {
synchronized (sHardBitmapCache) {
sHardBitmapCache.put(url, bitmap);
}
}
}
private Bitmap getBitmapFromCache(String url) {
synchronized (sHardBitmapCache) {
final Bitmap bitmap = sHardBitmapCache.get(url);
if (bitmap != null) {
sHardBitmapCache.remove(url);
sHardBitmapCache.put(url, bitmap);
return bitmap;
}
}
SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
if (bitmapReference != null) {
final Bitmap bitmap = bitmapReference.get();
if (bitmap != null) {
return bitmap;
} else {
sSoftBitmapCache.remove(url);
}
}
return null;
}
public void clearCache() {
sHardBitmapCache.clear();
sSoftBitmapCache.clear();
}
private void resetPurgeTimer() {
purgeHandler.removeCallbacks(purger);
purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE);
}
}
方法三:
/*package com.android.dieke.util;
import java.net.URL;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import com.dieke._class.FoodInfo;
import com.dieke.adapter.GridAllFoodAdapter;
public class ImageLoadTask extends AsyncTask<Void, Void, Void> {
private static final String TAG = ImageLoadTask.class.getSimpleName();
private GridAllFoodAdapter adapter;
public ImageLoadTask(Context context, GridAllFoodAdapter adapter) {
Log.v(TAG, "ImageLoadTask()");
this.adapter = adapter;
}
@Override
protected void onPreExecute() {
Log.v(TAG, "onPreExecute()");
}
@Override
protected Void doInBackground(Void... voids) {
Log.v(TAG, "doInBackground()");
for (int i = 0; i < adapter.getCount(); i++) {
FoodInfo bean = adapter.getItem(i);
try {
Log.d(TAG, bean.getFoodImgSrc());
URL url = new URL(bean.getFoodImgSrc());
Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());
Log.d(TAG, (bitmap == null) + "");
if (bitmap != null) {
bean.setBitmap(bitmap);
publishProgress();
}
} catch (Exception e) {
}
}
return null;
}
@Override
public void onProgressUpdate(Void... voids) {
Log.v(TAG, "onProgressUpdate()");
if (isCancelled())
return;
adapter.notifyDataSetChanged();
}
@Override
protected void onPostExecute(Void result) {
Log.v(TAG, "onPostExecute()");
}
}
*/
相关文章推荐
- 转载 Android实现ListView异步加载图片
- 转载:Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android实现异步加载图片 ListView
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android 实现ListView异步加载图片
- Android系列之ListView实现分页和类似异步加载效果(转载)
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android之ListView异步加载网络图片(优化缓存机制)和对图片资源进行优化,并且实现内存双缓存 + 磁盘缓存
- Android实现异步从网络加载图片列表和上拉加载更多、下拉刷新列表(使用xListView框架实现)
- android ListView异步加载图片,完美实现图文混排
- Android实现ListView异步加载图片的方法
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片
- Android实现ListView异步加载图片+缓存+线程池管理