欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android第三方库隔离之对第三方图片加载库的隔离

程序员文章站 2024-01-17 19:47:10
...
        在开发项目中引入第三方库总是不可避免的事,但是如果在代码中直接调用第三方库的方法,对于项目的灵活性也是不够的。如果遇到我们必须要更换其它框架的时候,那么整个项目中所有具体用到该框架的地方都需要更换,所有具体的调用方法都要一一更改,稍有疏忽还会引起不必要的bug,这个时候如果能将第三方库隔离开来,在具体代码中不直接执行第三方库的方法,而是交给一个可以统一调度第三方库的管理层就好了,这其实就是一种再封装抽离的过程,在具体需要调用的时候不直接调用第三方库的方法,而是调用我们自己封装的方法。

1、第三方图片加载库的使用方法大都雷同,可以抽离出一些公共的接口,当需要更换不同的图片框架的时候,只需要实现该接口,然后再调用该框架下对应的方法即可。


import android.content.Context;
import android.widget.ImageView;

public interface ImageLoader {

	/**
	 * 初始化一些必要的配置信息
	 * @param context
	 */
	public void init(Context context);

	/**
	 * 展示图片,同时参数resId可以设置默认的图片
	 * @param imageUrl
	 * @param imageView
	 * @param resId
	 *            defaultImage
	 */
	public void displayImage(String imageUrl, ImageView imageView, int resId);

	/**
	 * 展示图片,同时参数ImageLoadingListener可以设置对图片加载过程的监听
	 * @param imageUrl
	 * @param imageView
	 * @param resId
	 * @param loadingListener
	 */
	public void displayImage(String imageUrl, ImageView imageView, int resId, ImageLoadingListener loadingListener);

	/**
	 * 清除缓存
	 * @param imageUrl
	 */
	public void clearCache(String imageUrl);

}


2、实现 ImageLoader接口,在实现的方法中调用第三图片加载库的具体执行方法,这里使用的是universalimageloader框架。


import com.hi.imageloader.AutoImageDownloader;
import com.hi.imageloader.ImageLoader;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import com.nostra13.universalimageloader.utils.DiskCacheUtils;
import com.nostra13.universalimageloader.utils.MemoryCacheUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import android.widget.ImageView;

/**
 * 当前是使用UniversalImageLoader来展示项目中的图片,所以创建 UniversalImageLoader 类实现 ImageLoader 接口
 *
 */
public class UniversalImageLoader implements ImageLoader {

	private com.nostra13.universalimageloader.core.ImageLoader imageLoader = com.nostra13.universalimageloader.core.ImageLoader
			.getInstance();

	@Override
	public void init(Context context) {
		if (!imageLoader.isInited()) {
			ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(context)
					.threadPriority(Thread.NORM_PRIORITY - 2).denyCacheImageMultipleSizesInMemory()
					.discCacheFileNameGenerator(new Md5FileNameGenerator())
					.tasksProcessingOrder(QueueProcessingType.LIFO).imageDownloader(new AutoImageDownloader(context))
					.build();
			com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(configuration);
		}
	}

	@Override
	public void displayImage(String imageUrl, ImageView imageView, int defaultImage) {
		DisplayImageOptions options = new DisplayImageOptions.Builder().cacheOnDisc(true).cacheInMemory(true)
				.showStubImage(defaultImage).showImageForEmptyUri(defaultImage).showImageOnFail(defaultImage).build();
		imageLoader.displayImage(imageUrl, imageView, options);
	}

	@Override
	public void displayImage(String imageUrl, ImageView imageView, int defaultImage,
			final com.hi.imageloader.ImageLoadingListener loadingListener) {
		DisplayImageOptions options = new DisplayImageOptions.Builder().cacheOnDisc(true).cacheInMemory(true)
				.showStubImage(defaultImage).showImageForEmptyUri(defaultImage).showImageOnFail(defaultImage).build();
		imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {

			@Override
			public void onLoadingStarted(String arg0, View arg1) {
				loadingListener.onLoadingStarted(arg0);
			}

			@Override
			public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
				loadingListener.onLoadingFailed(arg0);
			}

			@Override
			public void onLoadingComplete(String str, View arg1, Bitmap bitmap) {
				loadingListener.onLoadingComplete(str, bitmap);
			}

			@Override
			public void onLoadingCancelled(String arg0, View arg1) {
				loadingListener.onLoadingCancelled(arg0);
			}
		});
	}

	@Override
	public void clearCache(String imageUrl) {
		DiskCacheUtils.removeFromCache(imageUrl, imageLoader.getDiskCache());
		MemoryCacheUtils.removeFromCache(imageUrl, imageLoader.getMemoryCache());
	}

}


3、第三方的图片加载库一般都有对图片加载过程的监听,并且有时候我们也有必要使用图片监听做一些具体业务逻辑上的处理,或者UI效果的处理等,所以我们抽象一个图片加载过程的接口也是很有必要的。

/**
 * 图片加载的监听接口
 * 
 * @author luzhaosheng
 *
 */
public interface ImageLoadingListener {

	public void onLoadingStarted(Object arg0);

	public void onLoadingFailed(Object arg0);

	public void onLoadingComplete(Object arg0, Object arg1);

	public void onLoadingCancelled(Object arg0);

}

4、使用代理模式,如果更换其它图片加载库,只需要更换代理对象,这样就实现了对第三方图片库的隔离,而项目中其它需要调用图片的方法都不需要更改。



import com.hi.imageloader.impl.UniversalImageLoader;
import android.content.Context;
import android.widget.ImageView;

/**
 * 图片加载代理类,如果更换了其它图片加载框架,只需要更换代理对象即可
 * 
 */
public class ImageLoaderProxy implements ImageLoader {

	private static ImageLoaderProxy imageLoaderProxy;
	private ImageLoader imageLoader;// 代理对象

	private ImageLoaderProxy() {
		imageLoader = new UniversalImageLoader();
	}
	
	public static ImageLoaderProxy getInstance() {
		if (imageLoaderProxy == null) {
			imageLoaderProxy = new ImageLoaderProxy();
		}
		return imageLoaderProxy;
	}

	@Override
	public void init(Context context) {
		imageLoader.init(context);
	}

	@Override
	public void displayImage(String imageUrl, ImageView imageView, int resId) {
		imageLoader.displayImage(imageUrl, imageView, resId);
	}

	@Override
	public void displayImage(String imageUrl, ImageView imageView, int resId, ImageLoadingListener loadingListener) {
		imageLoader.displayImage(imageUrl, imageView, resId, loadingListener);
	}

	@Override
	public void clearCache(String imageUrl) {
		imageLoader.clearCache(imageUrl);
	}

}

5、具体的使用:
     
      ⒈在Application中初始化:



import com.hi.imageloader.ImageLoaderProxy;
import android.content.Context;

/**
 * 
 */
public class MyApplication extends Application {

    private Context mContext;

	@Override
	public void onCreate() {
	    mContext = getApplicationContext();
		super.onCreate();
		init();
	}

	public void init() {
		// 图片加载器初始化
		ImageLoaderProxy.getInstance().init(mContext);
	}

}


      ⒉加载图片时可调用的方法,如:
          ImageLoaderProxy.getInstance().displayImage(imageUrl, imageView, R.drawable.image);
          或者在需要的时候加上监听:
          ImageLoaderProxy.getInstance().displayImage(imageUrl, imageView,, R.drawable.image,
                        new ImageLoadingListener() {

                            @Override
                            public void onLoadingStarted(Object arg0) {
                                // TODO Auto-generated method stub
                            }

                            @Override
                            public void onLoadingFailed(Object arg0) {
                                // TODO Auto-generated method stub
                                
                            }

                            @Override
                            public void onLoadingComplete(Object arg0, Object arg1) {
                                // TODO Auto-generated method stub
                            
                            }

                            @Override
                            public void onLoadingCancelled(Object arg0) {
                               // TODO Auto-generated method stub
                                
                            }
                        });

这就是对第三方图片加载库的一种隔离方式,这样之后如果需要更改使用其它框架,如:Glide、Fresco或者Picasso等,只需要添加一个ImageLoader的实现类,然后在代理类ImageLoaderProxy中替换代理对象即可。

     感谢所有!