GridView图片异步显示

http://www.eoeandroid.com/thread-210082-1-1.html
Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式


朋友们,先上效果图:
[img]
[img]http://dl.iteye.com/upload/attachment/0071/5143/ee4c5be8-478a-39c7-9f91-073e63dfc175.jpg[/img]
[/img]

[img]
[img]http://dl.iteye.com/upload/attachment/0071/5145/7531a712-3ba2-3f4d-9ce7-3789442b4b85.jpg[/img]
[/img]

工程结构图:
[img]
[img]http://dl.iteye.com/upload/attachment/0071/5147/cc15a115-5b64-3de1-83ac-26af60562c96.jpg[/img]
[/img]

RemoteImageView
package com.amaker.pic;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.widget.ImageView;

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 java.util.concurrent.RejectedExecutionException;


/**
* ImageView extended class allowing easy downloading
* of remote images
*/
public class RemoteImageView extends ImageView{

public static HashMap<String,Bitmap> imageCache = new HashMap<String, Bitmap>();

private static final int MAX_FAIL_TIME = 5;
private int mFails = 0;

private String mUrl;
//========
private ImageCache mapCache;
public RemoteImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void setDefaultImage(int resId){
this.setImageResource(resId);
}

public void setImageUrl(String url){

if(mUrl != null && mUrl.equals(url)){
mFails++;
}else{
mFails = 0;
mUrl = url;
}

if(mFails >= MAX_FAIL_TIME)
return;

mUrl = url;

if(isCached(url))
return;

startDownload(url);
}

public boolean isCached(String url){
if(imageCache.containsKey(url)){
this.setImageBitmap(imageCache.get(url));
return true;
}

return false;
}

private void startDownload(String url){
try{
new DownloadTask().execute(url);
}catch (RejectedExecutionException e) {
//捕获RejectedExecutionException同时加载的图片过多而导致程序崩溃
}
}

private void reDownload(String url){
setImageUrl(url);
}

class DownloadTask extends AsyncTask<String, Void, String>{

private String imageUrl;

@Override
protected String doInBackground(String... params) {
imageUrl = params[0];
InputStream is = null;
Bitmap bmp = null;

try {
URL url = new URL(imageUrl);
is = url.openStream();
bmp = BitmapFactory.decodeStream(is);
if(bmp != null){
imageCache.put(imageUrl, bmp);
}else{
reDownload(imageUrl);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(is != null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

return imageUrl;
}

@Override
protected void onPostExecute(String result) {
Bitmap bmp = null;
if(imageCache.containsKey(result)){
bmp = imageCache.get(result);
RemoteImageView.this.setImageBitmap(bmp);
}else{
reDownload(imageUrl);
}

super.onPostExecute(result);
}

}

}


RemoteAdapter
package com.amaker.pic;


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.List;

public class RemoteAdapter extends BaseAdapter {

private Context mContext;
private List<String> urls;
private LayoutInflater inflater;

public RemoteAdapter(Context context,List<String> urls){
mContext = context;
this.urls = urls;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public int getCount() {
return urls.size();
}

@Override
public Object getItem(int arg0) {
return urls.get(arg0);
}

@Override
public long getItemId(int arg0) {
return arg0;
}

@Override
public View getView(int position, View convertView, ViewGroup root) {

final ViewHolder holder;

if(convertView == null){
convertView = inflater.inflate(R.layout.item_layout, null);
holder = new ViewHolder();
holder.imageView = (RemoteImageView)convertView.findViewById(R.id.remote_image_view);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}

holder.imageView.setDefaultImage(R.drawable.default_image);
holder.imageView.setImageUrl(urls.get(position));

return convertView;
}

class ViewHolder{
RemoteImageView imageView;
}

}


ImageCache
package com.amaker.pic;

import java.util.WeakHashMap;

import android.graphics.Bitmap;

public class ImageCache extends WeakHashMap<String, Bitmap> {

private static final long serialVersionUID = 1L;

public boolean isCached(String url){
return containsKey(url) && get(url) != null;
}

}


AsyncDownPicDemoActivity
package com.amaker.pic;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.GridView;

import java.util.Arrays;
import java.util.List;

public class AsyncDownPicDemoActivity extends Activity {

private GridView mGridView;
private Context mContext;
private List<String> urlList;
private RemoteAdapter mRemoteAdapter;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
private void init(){
mContext = this;
mGridView = (GridView)findViewById(R.id.grid_view);
urlList = Arrays.asList(new String[]{
"http://www.chinatelecom.com.cn/images/logo_new.gif"
,"http://t03.pic.sogou.com/945b578c3b6057be.jpg"
,"http://t03.pic.sogou.com/3a4feb9c3b6057be.jpg"
,"http://t02.pic.sogou.com/eb95234678ecb28d.jpg"
,"http://t01.pic.sogou.com/a240ade96f0fbe20.jpg"
,"http://t04.pic.sogou.com/e72ead334e356f27.jpg"
,"http://t01.pic.sogou.com/166bb3e4026f1294.jpg"
,"http://t01.pic.sogou.com/bf593d46dc85ff10.jpg"
,"http://t04.pic.sogou.com/a7bedc2a13f3045f.jpg"
,"http://t02.pic.sogou.com/c323b5e10071eed5.jpg"
,"http://www.baidu.com/img/baidu_logo.gif"
,"http://t01.pic.sogou.com/0165d7241d6cd80c.jpg"
,"http://cache.soso.com/30d/img/web/logo.gif",
"http://csdnimg.cn/www/images/csdnindex_logo.gif"
,"http://samsung.tgbus.com/UploadFiles_3297/201207/2012071009241894.jpg"
,"http://t01.pic.sogou.com/746bf1a4484d8dd4.jpg"
,"http://www.icoou.com/news_img/20110301/1109150.jpg"
,"http://images.cnblogs.com/logo_small.gif"
,"http://t04.pic.sogou.com/84b8341f7346b9c7.jpg"
,"http://t03.pic.sogou.com/ca11112c3b6057be.jpg"
,"http://t02.pic.sogou.com/56cbda8df459a4e1.jpg"
,"http://t04.pic.sogou.com/64918bba09a4884b.jpg"
,"http://t04.pic.sogou.com/bda625f4bff15e0b.jpg"
,"http://t01.pic.sogou.com/5d9a94e179fb5f08.jpg"
,"http://www.chinatelecom.com.cn/images/logo_new.gif"
,"http://t03.pic.sogou.com/945b578c3b6057be.jpg"
,"http://t03.pic.sogou.com/3a4feb9c3b6057be.jpg"
,"http://t02.pic.sogou.com/eb95234678ecb28d.jpg"
,"http://t01.pic.sogou.com/a240ade96f0fbe20.jpg"
,"http://t04.pic.sogou.com/e72ead334e356f27.jpg"
,"http://t01.pic.sogou.com/166bb3e4026f1294.jpg"
,"http://t01.pic.sogou.com/bf593d46dc85ff10.jpg"
,"http://t04.pic.sogou.com/a7bedc2a13f3045f.jpg"
,"http://t02.pic.sogou.com/c323b5e10071eed5.jpg"
,"http://www.baidu.com/img/baidu_logo.gif"
,"http://t01.pic.sogou.com/0165d7241d6cd80c.jpg"
,"http://cache.soso.com/30d/img/web/logo.gif",
"http://csdnimg.cn/www/images/csdnindex_logo.gif"
,"http://samsung.tgbus.com/UploadFiles_3297/201207/2012071009241894.jpg"
,"http://t01.pic.sogou.com/746bf1a4484d8dd4.jpg"
,"http://www.icoou.com/news_img/20110301/1109150.jpg"
,"http://images.cnblogs.com/logo_small.gif"
,"http://t04.pic.sogou.com/84b8341f7346b9c7.jpg"
,"http://t03.pic.sogou.com/ca11112c3b6057be.jpg"
,"http://t02.pic.sogou.com/56cbda8df459a4e1.jpg"
,"http://t04.pic.sogou.com/64918bba09a4884b.jpg"
,"http://t04.pic.sogou.com/bda625f4bff15e0b.jpg"
,"http://t01.pic.sogou.com/5d9a94e179fb5f08.jpg"
});
mRemoteAdapter = new RemoteAdapter(mContext, urlList);
mGridView.setAdapter(mRemoteAdapter);
}
}


item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<com.amaker.pic.RemoteImageView
android:id="@+id/remote_image_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitXY"
/>

</LinearLayout>



main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<GridView
android:id="@+id/grid_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="3"
/>

</LinearLayout>


AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amaker.pic"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="AsyncDownPicDemoActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

[code="java"][/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值