`
hunankeda110
  • 浏览: 746542 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

android中异步加载图片

阅读更多
浅谈Android ListView 异步图片获取




         Android应用中,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量,而且如果加载在图片比较多的View中,如ListView GridView WebView中,加载速度会比较缓慢。Android中图片加载速度很慢的话,程序很容易就挂掉,等待的用户用户同样会等到崩溃。

我们一般的处理方法是:



异步下载


本地缓存



-----------------------------------------------------------
先说异步下载






如一个ListView的异步下载



Java代码 
1.public class AsyncActivity extends Activity  {  
2.    List<data> insList;  
3.    private ListView mListView;  
4.    private ArrayList<data> mListItems;  
5.    private ItemAdapter mAdapter;  
6.    private ImageView mLfteView;  
7.    private ImageView mRightView;  
8.      
9.      
10. 
11.    private static final int REFRESH_LIST = 1;  
12.    Handler mHandler = new Handler() {  
13.        public void handleMessage(android.os.Message msg) {  
14.            int type = msg.what;  
15.            switch (type) {  
16.            case REFRESH_LIST: {  
17.              
18.                if (mListItems.size() > 0) {  
19.                    mListView.setVisibility(View.VISIBLE);  
20.                    if (mAdapter== null) {  
21.                        mAdapter = new Adapter(AsyncActivity.this,  
22.                                mListItems);  
23.                        mListView.setAdapter(mAdapter);  
24.                    }  
25.                        mAdapter.notifyDataSetChanged();  
26. 
27.                }  
28.                mListView.requestFocus();  
29.                  
30.                unShowDialogLoading();  
31.                break;  
32.            }  
33. 
34.          
35.            default:  
36.                break;  
37.            }  
38.        };  
39.    };  
40. 
41.      
42.    public void onCreate(Bundle savedInstanceState) {   
43.        super.onCreate(savedInstanceState);   
44.        setContentView(R.layout.insurance_list);   
45.        initViews();  
46.        getList();  
47.    }   
48.    
49.    /** 
50.     * 初始化view 
51.     */ 
52.    private void initViews(){  
53.          
54.        mListView = (ListView)findViewById(R.id.list);  
55.        mListView.setAdapter(mAdapter);  
56.        mListView.setOnItemClickListener(new OnItemClickListener(){  
57.            public void onItemClick(AdapterView<?> arg0, View v, int id,  
58.                    long pos) {  
59.                // 获得被单击的项       
60.                //跳转  
61.              
62.            }  
63.        });  
64.     
65.          
66.        mListItems = new ArrayList<data>();  
67. 
68.    }  
69. 
70.      
71.    
72.    private void getList() {  
73.        showDialogLoading();  
74.         //得到保险列表  
75.        insuranceData insurance = new insuranceData();  
76.        insList = insurance.getList();  
77.        mListItems.clear();  
78.        mListItems.addAll(insList);  
79.        mHandler.sendEmptyMessage(REFRESH_LIST);  
80.          
81.          
82.    }  
83.      
84. 
85.    private ProgressDialog mLoadingDialog;  
86. 
87.    private void showDialogLoading() {  
88.        mLoadingDialog = new ProgressDialog(this);                   
89.        mLoadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);  
90.         //spinner  自旋体 像螺旋桨那样                               
91.        mLoadingDialog.setMessage("载入中,请稍候...");                   
92.        mLoadingDialog.setIndeterminate(false);//设置进度条是否为不明确                  
93.        mLoadingDialog.setCancelable(true);//设置进度条是否可以按退回健取消                                 
94.        mLoadingDialog.show();   
95.    }  
96. 
97.    private void unShowDialogLoading() {  
98.        if (mLoadingDialog == null)  
99.            return;  
100.        else 
101.            mLoadingDialog.dismiss();  
102.    }  
103.      
104.} 
public class AsyncActivity extends Activity  {
List<data> insList;
private ListView mListView;
private ArrayList<data> mListItems;
private ItemAdapter mAdapter;
private ImageView mLfteView;
private ImageView mRightView;



private static final int REFRESH_LIST = 1;
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
int type = msg.what;
switch (type) {
case REFRESH_LIST: {

if (mListItems.size() > 0) {
mListView.setVisibility(View.VISIBLE);
if (mAdapter== null) {
mAdapter = new Adapter(AsyncActivity.this,
mListItems);
mListView.setAdapter(mAdapter);
}
mAdapter.notifyDataSetChanged();

}
mListView.requestFocus();

unShowDialogLoading();
break;
}


default:
break;
}
};
};


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.insurance_list);
        initViews();
        getList();
    }
 
    /**
     * 初始化view
     */
    private void initViews(){
   
    mListView = (ListView)findViewById(R.id.list);
    mListView.setAdapter(mAdapter);
    mListView.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View v, int id,
long pos) {
    // 获得被单击的项    
        //跳转
   
}
    });
  
   
    mListItems = new ArrayList<data>();

    }

   
 
    private void getList() {
    showDialogLoading();
    //得到保险列表
        insuranceData insurance = new insuranceData();
        insList = insurance.getList();
        mListItems.clear();
        mListItems.addAll(insList);
        mHandler.sendEmptyMessage(REFRESH_LIST);
       
       
    }
   

    private ProgressDialog mLoadingDialog;

private void showDialogLoading() {
mLoadingDialog = new ProgressDialog(this);                
mLoadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//spinner  自旋体 像螺旋桨那样                            
mLoadingDialog.setMessage("载入中,请稍候...");                
mLoadingDialog.setIndeterminate(false);//设置进度条是否为不明确               
mLoadingDialog.setCancelable(true);//设置进度条是否可以按退回健取消                              
mLoadingDialog.show();
}

private void unShowDialogLoading() {
if (mLoadingDialog == null)
return;
else
mLoadingDialog.dismiss();
}

}

它的Adapter是




Java代码 
1.public class InsuranceItemAdapter extends BaseAdapter{  
2.    private ArrayList<data> mList;  
3.    private Context mContext;  
4.    // 异步加载图片的线程  
5.    private AsyncImageLoader imageLoader = new AsyncImageLoader();  
6.    //当前的缓存  
7.    private Map<Integer, View> viewMap = new HashMap<Integer, View>();  
8. 
9.    public InsuranceItemAdapter(Context context, ArrayList<data> ins) {  
10.        mContext = context;  
11.        mList= ins;  
12.    }  
13. 
14.    public InsuranceItemAdapter(Context context, ArrayList<data> ins,  
15.            Handler handler) {  
16.        mContext = context;  
17.        mList= ins;  
18.    }  
19. 
20.    public void setInsurance(ArrayList<data> ins) {  
21.        mList= ins;  
22.    }  
23.      
24.      
25.      
26.    public int getCount() {  
27.        return mList.size();  
28.    }  
29. 
30.    public Object getItem(int position) {  
31.        try {  
32.            return mList.get(position);  
33.        } catch (Exception ex) {  
34.            return null;  
35.        }  
36.    }  
37. 
38.    public long getItemId(int position) {  
39.        return position;  
40.    }  
41. 
42.      
43.    private View newView() {  
44.        ItemView view = new ItemView(mContext);  
45.        return view;  
46.    }  
47.      
48.      
49.      
50.    public View getView(int position, View convertView, ViewGroup parent) {  
51.        //先从缓存里面读取  
52.        ViewHolder holder = null;    
53.        View view;    
54.          
55.         if (viewMap.get(position) == null) {    
56.            view = newView();  
57.            holder = new ViewHolder();    
58.            holder.mTitle = (TextView)view.findViewById(R.id.ins_title);  
59.            holder.mTime = (TextView)view.findViewById(R.id.ins_time);  
60.            holder.mType = (TextView)view.findViewById(R.id.ins_from);  
61.            holder.mPic = (ImageView)view.findViewById(R.id.ins_small_pic);  
62.            final int p = position;    
63.            viewMap.put(position, view);    
64.            view.setTag(holder);    
65.         }else{  
66.             Log.e("MainActivity","position2 = "+position);    
67.             view = viewMap.get(position);    
68.             holder = (ViewHolder)view.getTag();    
69.         }  
70.          
71.         data ins = mList.get(position);  
72.         holder.mTitle.setText(ins.getTitle());  
73. 
74.          
75.        holder.mPic.setVisibility(View.VISIBLE);  
76.          
77.        // 异步加载图片  
78.        Drawable cachedImage = imageLoader.loadDrawable(ins.getPic(), holder.mPic,  
79.                new ImageCallback() {  
80.                    public void imageLoaded(Drawable imageDrawable,  
81.                            ImageView imageView, String imageUrl) {  
82.                        imageView.setImageDrawable(imageDrawable);  
83.                    }  
84.                });  
85.        if (cachedImage != null) {  
86.            holder.mPic.setImageDrawable(cachedImage);  
87.        }  
88.           
89.         return view;    
90. 
91.    }  
92.      
93.      
94.    static class ViewHolder{    
95.        ImageView mPic;  
96.        TextView mTitle;  
97.        TextView mTime;  
98.        TextView mType;  
99.    }  
100.} 
public class InsuranceItemAdapter extends BaseAdapter{
private ArrayList<data> mList;
private Context mContext;
// 异步加载图片的线程
private AsyncImageLoader imageLoader = new AsyncImageLoader();
//当前的缓存
    private Map<Integer, View> viewMap = new HashMap<Integer, View>();

public InsuranceItemAdapter(Context context, ArrayList<data> ins) {
mContext = context;
mList= ins;
}

public InsuranceItemAdapter(Context context, ArrayList<data> ins,
Handler handler) {
mContext = context;
mList= ins;
}

public void setInsurance(ArrayList<data> ins) {
mList= ins;
}



public int getCount() {
return mList.size();
}

public Object getItem(int position) {
try {
return mList.get(position);
} catch (Exception ex) {
return null;
}
}

public long getItemId(int position) {
return position;
}


private View newView() {
ItemView view = new ItemView(mContext);
return view;
}



public View getView(int position, View convertView, ViewGroup parent) {
//先从缓存里面读取
ViewHolder holder = null; 
View view; 

if (viewMap.get(position) == null) { 
view = newView();
holder = new ViewHolder(); 
holder.mTitle = (TextView)view.findViewById(R.id.ins_title);
holder.mTime = (TextView)view.findViewById(R.id.ins_time);
holder.mType = (TextView)view.findViewById(R.id.ins_from);
holder.mPic = (ImageView)view.findViewById(R.id.ins_small_pic);
final int p = position; 
viewMap.put(position, view); 
            view.setTag(holder); 
}else{
Log.e("MainActivity","position2 = "+position); 
             view = viewMap.get(position); 
             holder = (ViewHolder)view.getTag(); 
}

data ins = mList.get(position);
holder.mTitle.setText(ins.getTitle());


holder.mPic.setVisibility(View.VISIBLE);

// 异步加载图片
Drawable cachedImage = imageLoader.loadDrawable(ins.getPic(), holder.mPic,
new ImageCallback() {
public void imageLoaded(Drawable imageDrawable,
ImageView imageView, String imageUrl) {
imageView.setImageDrawable(imageDrawable);
}
});
if (cachedImage != null) {
holder.mPic.setImageDrawable(cachedImage);
}
        
         return view; 

}


static class ViewHolder{ 
ImageView mPic;
TextView mTitle;
TextView mTime;
TextView mType;
}
}




原理简单,不罗嗦了




本地缓存

 

   就是先读取本地的数据,如果本地没有再从网络上获取



WebView中很简单,


Java代码 
1.//优先缓存  
2.        mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
//优先缓存
mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 就能实现了。





其他地方我们就得自己写一个异步图片下载了,


Java代码 
1.public class AsyncImageLoader {  
2. 
3.     //SoftReference是软引用,是为了更好的为了系统回收变量  
4.    private static HashMap<String, SoftReference<Drawable>> imageCache;  
5.      
6.    static {  
7.        imageCache = new HashMap<String, SoftReference<Drawable>>();  
8.    }  
9.      
10.      
11.    public AsyncImageLoader() {  
12.          
13.    }  
14.    public Drawable loadDrawable(final String imageUrl,final ImageView imageView, final ImageCallback imageCallback){  
15.        if (imageCache.containsKey(imageUrl)) {  
16.            //从缓存中获取  
17.            SoftReference<Drawable> softReference = imageCache.get(imageUrl);  
18.            Drawable drawable = softReference.get();  
19.            if (drawable != null) {  
20.                return drawable;  
21.            }  
22.        }  
23.        final Handler handler = new Handler() {  
24.            public void handleMessage(Message message) {  
25.                imageCallback.imageLoaded((Drawable) message.obj, imageView,imageUrl);  
26.            }  
27.        };  
28.        //建立新一个新的线程下载图片  
29.        new Thread() {  
30.            @Override 
31.            public void run() {  
32.                Drawable drawable = null;  
33.                try {  
34.                    drawable = ImageUtil.geRoundDrawableFromUrl(imageUrl, 20);  
35.                } catch (Exception e) {  
36.                    e.printStackTrace();  
37.                }  
38.                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));  
39.                Message message = handler.obtainMessage(0, drawable);  
40.                handler.sendMessage(message);  
41.            }  
42.        }.start();  
43.        return null;  
44.    }  
45.    //回调接口  
46.    public interface ImageCallback {  
47.        public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl);  
48.    }  
49.} 
public class AsyncImageLoader {

//SoftReference是软引用,是为了更好的为了系统回收变量
    private static HashMap<String, SoftReference<Drawable>> imageCache;
   
    static {
    imageCache = new HashMap<String, SoftReference<Drawable>>();
    }
   
   
    public AsyncImageLoader() {
       
    }
    public Drawable loadDrawable(final String imageUrl,final ImageView imageView, 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, imageView,imageUrl);
            }
        };
        //建立新一个新的线程下载图片
        new Thread() {
            @Override
            public void run() {
                Drawable drawable = null;
try {
drawable = ImageUtil.geRoundDrawableFromUrl(imageUrl, 20);
} catch (Exception e) {
e.printStackTrace();
}
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                Message message = handler.obtainMessage(0, drawable);
                handler.sendMessage(message);
            }
        }.start();
        return null;
    }
    //回调接口
    public interface ImageCallback {
        public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl);
    }
}



当然我们也可以存数据库中,从数据库中优先获取,当没有网络的时候达到离线阅读的功能。

分享到:
评论
2 楼 guanting207 2013-12-19  
trx999 写道
建议一下。关键代码可以贴出来。所有的不必要的代码贴出来只能让阅读者眼花缭乱,甚至思维混乱。你可以把小demo上传。思路清楚了,代码看起来就清楚了。

1 楼 trx999 2012-04-24  
建议一下。关键代码可以贴出来。所有的不必要的代码贴出来只能让阅读者眼花缭乱,甚至思维混乱。你可以把小demo上传。思路清楚了,代码看起来就清楚了。

相关推荐

    Android异步加载图片例子

    在这个"Android异步加载图片例子"中,我们将探讨如何在Android应用中实现这一功能。 首先,我们需要理解Android的主线程(UI线程)与工作线程的区别。主线程负责处理用户界面交互,而工作线程则用于执行耗时操作,...

    Android AsyncTask用法和异步加载图片.rar

    本资料包主要讲解了如何使用`AsyncTask`进行异步加载图片,这对于在UI线程中保持流畅用户体验至关重要。 `AsyncTask`是Android SDK中的一个类,它为开发者提供了简单的多线程和回调功能。它的核心思想是将长时间...

    使用Android Studio 练习RecyclerView 异步加载图片,解决图片乱序问题。

    然而,在实际开发中,当我们需要在RecyclerView中异步加载图片时,可能会遇到图片显示乱序的问题。本文将深入探讨这个问题及其解决方案。 首先,我们来理解为什么会出现图片乱序的现象。这是因为RecyclerView在滚动...

    Android 演示异步加载图片的实现 附源代码.rar

    Android 演示异步加载图片的实现 附源代码,这里主要是演示ListView的异步加载图片功能,异步加载一个view时,如果view里面有EditText,EditText在每次加载view都会触发焦点,这时候异步就会出错。可能我这样说不太...

    Android Listview异步加载图片

    本文将深入探讨Android ListView中异步加载图片的策略、常见问题以及解决方案。 首先,我们要理解异步加载的基本原理。异步加载是指在后台线程中执行耗时操作,如加载图片,而主线程则继续处理用户交互,保证界面...

    Android 图片异步加载 加载网络图片

    在Android应用开发中,图片加载是一项常见的任务,尤其是在处理大量图片或者网络图片时,为了提供良好的用户体验,我们通常会采用异步加载的方式。本篇将深入探讨Android平台上的图片异步加载策略,以及如何加载网络...

    android Gridview 异步加载网络图片

    在GridView中异步加载网络图片是一项重要的技能,特别是在构建图片丰富的应用如相册或社交媒体应用时。本示例适用于API级别17及以上,因为它是针对Android 4.2(Jelly Bean)及更高版本设计的。 1. ** GridView的...

    android listView 异步加载图片

    这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...

    Android实现ListView异步加载图片

    本文将详细介绍 Android 中实现 ListView 异步加载图片的方法,并对相关的技术概念进行解释。 1. 异步加载图片的必要性 在 Android 应用程序中,加载图片是一个耗时的操作,特别是在 ListView 中。如果不使用异步...

    Android中实现异步加载图片的Demo

    在Android开发中,异步加载图片是一项至关重要的技术,它能显著提升用户体验,尤其是在处理大量图片数据时。这个"Android中实现异步加载图片的Demo"展示了如何在Android应用中高效地加载和显示图片,无论是从本地...

    android异步加载图片

    "Android异步加载图片"是一个常见的需求,它涉及到用户体验优化、内存管理以及线程安全等多个方面。这里我们将深入探讨这个主题,并结合提供的"ImageLoader-develop"可能是一个图片加载库的源码,来讲解相关的知识点...

    Android 异步加载图片实现_图片缓存.zip

    综上所述,Android异步加载图片和缓存策略是提升应用性能的关键技术。通过合理使用工作线程和缓存机制,可以显著改善用户体验,降低系统负载。在实际开发中,选择合适的图片加载库,并结合最佳实践,能够帮助我们...

    Android ListView异步加载图片

    Android 异步加载图片,对ListView的异步加载图片的功能演示,主要根据url读取图片返回流的方法。为了方便演示,将请求图片的链接先固定,每读取好一个图片就更新,界面比较简单,当然你可以做成比较好的,像很多好...

    Android图片异步加载-ListView、GridView、ViewPager

    总的来说,Android-Universal-Image-Loader为Android开发者提供了一种高效、灵活的图片异步加载解决方案,无论是ListView、GridView还是ViewPager,都可以通过其强大的功能提升用户体验。在实际开发中,掌握这个库的...

    Android用AsyncTask异步加载图片(新)

    在Android应用开发中,异步加载图片是一项常见的需求,特别是在处理大数据量的图像时,如在GridView或ListView中展示图片。`AsyncTask`是Android提供的一种轻量级的多线程解决方案,它允许开发者在后台执行耗时操作...

    Android 异步加载图片缓存优化.rar

    总的来说,Android异步加载图片缓存优化是通过合理利用内存和磁盘资源,配合高效的异步处理,为用户提供流畅的图片浏览体验,同时避免了由于大图加载引发的内存问题。开发者可以通过学习这个压缩包中的源码和文档,...

    Android实现异步加载图片

    首先,Android异步加载图片的目标是将耗时的网络请求或本地文件读取操作放在后台线程,以防止阻塞主线程。Android提供了一些工具和库来帮助开发者实现这一目标,如AsyncTask、Handler、Loader等。在这个例子中,我们...

    android listView图片异步加载(拖动时不加载,双缓存)

    本文将详细介绍如何在ListView中实现图片的异步加载,并且在用户拖动时不加载,以提高滚动流畅性。 一、异步加载原理 异步加载是指在后台线程中执行耗时操作,例如网络请求或解码图片,避免阻塞主线程。Android提供...

    Android中ListView全面完美的网络图片的异步加载

    "Android中ListView全面完美的网络图片异步加载"这一主题正是解决这些问题的关键。 首先,我们需要理解异步加载的概念。异步加载意味着在后台线程处理耗时操作,如下载和解码图片,而不是在主线程中执行,这样可以...

Global site tag (gtag.js) - Google Analytics