Android-Universal-Image-Loader开源项目应用

来源:互联网 发布:手机淘宝买东西的流程 编辑:程序博客网 时间:2024/04/25 22:24

应用中图片的加载速度和图片的显示效果直接关系到用户的体验,也关系到应用得成败,你可以想象一下在一个应用中如果显示图片速度需要几分钟甚至10几分钟,可想而知你的应用将要面对什么样的命运。今天和同事讨论了一下安卓图片的加载问题,觉得图片的加载方式可以通过是内存缓存+本地存储+服务器获取三种方式结合是使用,为什么呢?

   一.图片处理方式分析

       内存缓存:无疑的这种方式速度是最快的,但是考虑到如果有大量的图片需要处理,那么对于我们的有限内存的手机来说这种体验将是非常糟糕的,如果超出了虚拟机(JVM)分配给这个应用的最大内存,它就会报OOM(内存溢出)错误;当然我们也可以设置缓存的大小,通过程序来控制缓存的的清理,如,时间周期清理或者按照图片的使用频率等方式,这种方式不会报错,但是图片的存储容量是很小的。

      优点:加载速度快 占用空间少      缺点:占用内存多 不持久化

    本地存储:这种存储方式相对第一种来说速度会慢点,现在的手机SD卡来说读取速度还是不错的,其实我们也可以单独采取这种方式来处理图片。可以采取和第一种相同的处理方式来控制图片缓存的大小,不过相对于第一种可用的空间会大的多。

    优点:可用的缓存空间相对较多  不占用内存   缺点:常用的未驻内存


    所以说我们可以采用内存缓存和本地存储的方式来对图片进行处理,这种方式既能够利用内存缓存速度快的优点,又能够通过本地存储来扩展缓存空间;其中内存缓存用来存储频率较高的图片,本地存储扩展存储剩下图片。具体的做法是:

  (1)第一次打开应用时,自动存储完程序分配好的内存空间缓存,如果有多余的图片则存储到SD卡中,如果还有多余则覆盖SD卡中前面已经存储的。

  (2)再次打开应用时,则判断图片是否已经存在(先和内存比较然后和SD卡中比较),如果存在则直接加载,并且让使用频率加1,同时比较频率使用次数,来判断哪些需要加载到内存缓存中,那些放在SD卡中;如果不存在则从网络中下载图片,空间不足则自动覆盖掉前面使用频率较少,或者时间过期的图片。



二. Android-Universal-Image-Loader开源项目

    今天的主角出来了,Android-Universal-Image-Loader开源项目(点击打开链接),该项目提供了非常多的接口,并且使用了三种方式来对图片进行处理。

        具体的原理可以参考博客浅谈开源项目Android-Universal-Image-Loader(Part 3.1)和开源项目:Android-Universal-Image-Loader总结

    (1)项目引用

    下子文件在downloads文件夹中将universal-image-loader-1.8.4.jar文件引入到项目中



  (2)参数设置

     Android-Universal-Image-Loader有很多的参数设置,具体的可以去查看文档,例子只给出了常见的设置

public class MainActivity extends Activity {ListView listView;String pathex="https://lh6.googleusercontent.com/-jZgveEqb6pg/T3R4kXScycI/AAAAAAAAAE0/xQ7CvpfXDzc/s1024/sample_image_01.jpg";//<span style="color:#ff0000;">图片的http://地址,请自己添加,这里的地址不一定可以使用</span>String[] imageUrls=new String[]{pathex,pathex,pathex,pathex};DisplayImageOptions options;ImageLoader imageLoader = ImageLoader.getInstance();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView=(ListView) findViewById(android.R.id.list);//android.R表示是内置的资源options = new DisplayImageOptions.Builder().showStubImage(R.drawable.pdt_sample)// 设置图片在下载期间显示的图片.showImageForEmptyUri(R.drawable.pdt_sample)// 设置图片Uri为空或是错误的时候显示的图片.showImageOnFail(R.drawable.pdt_sample)// 设置图片加载/解码过程中错误时候显示的图片.cacheInMemory()// 是否緩存都內存中.cacheOnDisc()// 是否緩存到sd卡上.displayer(new SimpleBitmapDisplayer()).build();//图片显示方式为正常显示ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).threadPriority(Thread.NORM_PRIORITY - 2)// 设置线程的优先级.denyCacheImageMultipleSizesInMemory()// 当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片.discCacheFileNameGenerator(new Md5FileNameGenerator())// 设置缓存文件的名字.discCacheFileCount(60)// 缓存文件的最大个数.tasksProcessingOrder(QueueProcessingType.LIFO)// 设置图片下载和显示的工作队列排序.build();//Initialize ImageLoader with configurationimageLoader.init(config);((ListView) listView).setAdapter(new ItemAdapter());listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {startImagePagerActivity(position);}});//ImageLoader.getInstance().displayImage("http://cms.kineticspace.net/taipo/POI/webapp/app/view/upload/1399014224.jpg", imageView); }@Overridepublic void onBackPressed() {AnimateFirstDisplayListener.displayedImages.clear();super.onBackPressed();}private void startImagePagerActivity(int position) {/*Intent intent = new Intent(this, ImagePagerActivity.class);intent.putExtra(Extra.IMAGES, imageUrls);intent.putExtra(Extra.IMAGE_POSITION, position);startActivity(intent);*/} @Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}class ItemAdapter extends BaseAdapter {private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();private class ViewHolder {public TextView text;public ImageView image;}@Overridepublic int getCount() {return imageUrls.length;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {View view = convertView;final ViewHolder holder;if (convertView == null) {view = getLayoutInflater().inflate(R.layout.item_list_shopcar, parent, false);holder = new ViewHolder();holder.text = (TextView) view.findViewById(R.id.text);holder.image = (ImageView) view.findViewById(R.id.image);view.setTag(holder);} else {holder = (ViewHolder) view.getTag();}holder.text.setText("Item " + (position + 1));imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);return view;}}private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());@Overridepublic void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {if (loadedImage != null) {ImageView imageView = (ImageView) view;boolean firstDisplay = !displayedImages.contains(imageUri);if (firstDisplay) {FadeInBitmapDisplayer.animate(imageView, 500);displayedImages.add(imageUri);}}}}}

布局文件:activity_main.xml

<?xml version="1.0" encoding="utf-8"?><ListView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@android:id/list"    android:layout_width="fill_parent"    android:layout_height="fill_parent"   android:background="#fff"    android:divider="#f00"    android:dividerHeight="0.5dp"/>
 

布局文件: item_list_shopcar.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="wrap_content" >    <ImageView        android:id="@+id/image"        android:adjustViewBounds="true"        android:contentDescription="@string/descr_image"        android:layout_width="80dp"        android:layout_height="80dp"        android:layout_margin="5dp"        android:scaleType="fitXY"/>    <TextView        android:id="@+id/text"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_gravity="left|center_vertical"        android:layout_marginLeft="20dip"        android:textSize="22sp" /></LinearLayout>


这里可以添加子页面,我们有添加具体可参考,项目的sample例子,今天就到这吧,下班收工。


1 0