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
RemoteAdapter
ImageCache
AsyncDownPicDemoActivity
item_layout.xml
main.xml
AndroidManifest.xml:
[code="java"][/code]
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]