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

应用中图片的加载速度和图片的显示效果直接关系到用户的体验,也关系到应用得成败,你可以想象一下在一个应用中如果显示图片速度需要几分钟甚至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();
	@Override
	protected 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 configuration
		imageLoader.init(config);
		((ListView) listView).setAdapter(new ItemAdapter());
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public 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); 
	}


	@Override
	public 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);*/
	} 

	@Override
	public 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;
		}

		@Override
		public int getCount() {
			return imageUrls.length;
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

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

		@Override
		public 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>());

		@Override
		public 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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值