在Android開發過程當中,咱們通常都會使用到第三方框架,隨着框架層出不窮,隨着項目的發展擴大,不排除會出現替換框架的狀況,例如:日誌框架,圖片框架,網絡框架等等;最初我在開發過程當中會直接引用第三方框架,直到後來須要替換框架的時候,才發現這個過程的工做量是巨大而且沒意義的,須要修改使用到框架的地方有幾十處(若是項目大,遠遠不止這個數目),那時候我就醒悟,必定要培養架構思想,不能應付式的實現了功能就認爲萬事大吉。後來在學習過程當中發現,使用策略模式能夠很友好的解決框架更換的問題,而且能夠經過一句代碼就輕鬆切換整個項目的框架。git
或許會有讀者認爲不必使用策略模式這麼麻煩,只須要將框架進行二次封裝,待須要修改的時候也能夠不影響其餘代碼。對於這種思路,我用圖片框架Universal-Image-Loader做爲例子簡單描述一下,貼上簡短的代碼便於清晰。github
/**
* 簡單封裝Universal-Image-Loader圖片加載的工具類
**/
public class ImageLoaderUtils {
private DisplayImageOptions mImageOptions;
public ImageLoaderUtils(){
//配置UIL的初始化
ImageLoaderConfiguration configuration = ImageLoaderConfiguration.createDefault(this);
ImageLoader.getInstance().init(configuration);
mImageOptions = DisplayImageOptions.createSimple();
}
//默認加載
public static void loadImageView(Context context, String imgUrl, ImageView view) {
ImageLoader.getInstance().displayImage(imgUrl, view, mImageOptions);
}
}複製代碼
封裝好的工具類在Activity中的示範以下:緩存
/**
* ImageLoaderUtils的使用示範
**/
public class ExampleActivity extends AppCompatActivity{
private ImageView mIvPhoto;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mIvPhoto = findViewById(R.id.iv_cover);
ImageLoaderUtils.loadImageView(this,"url",mIvPhoto);
}
}複製代碼
若是須要使用Glide框架替換如今的Universal-Image-Loader框架,直接修改ImageLoaderUtils工具類,這樣亦可實現不需修改全部使用到框架Universal-Image-Loader的地方。bash
/**
* 使用Glide替換Universal-Image-Loader的工具類
**/
public class ImageLoaderUtils {
//默認加載
public static void loadImageView(Context context, String imgUrl, ImageView view) {
Glide.with(context).load(imgUrl).into(view);
}
}複製代碼
這樣處理當然能夠替換框架,而且工做量不算大,但我認爲這種處理方式有必定的弊端,剔除了舊框架代碼,萬一往後新框架出現問題,處理工做就顯得麻煩,說白了就是這種處理方式不能並存兩種或兩種以上的框架方案,若是項目中須要切換框架的話就明顯感受到不靈活,因此我認爲引入策略模式是可取的。網絡
關於策略模式,這裏我就不詳細描述,往後抽空寫一篇關於「策略模式」的文章。架構
首先,咱們定義一個策略接口,用於存放框架之間會共同使用的方法,例如:默認加載圖片,加載GIf等等。app
/**
* 策略接口
**/
public interface BaseImageLoaderStrategy {
/**
* 默認方式加載圖片
* @param context 上下文
* @param view View 控件
* @param imgUrl 圖片URL
*/
void loadImage(Context context, ImageView view, Object imgUrl);
}
複製代碼
第二步:接下來寫實現類,這裏我使用Universal-Image-Loader爲例,簡單寫一個實現類。框架
/**
* Universal-Image-Loader的實現類
**/
public class UniversalLoaderStrategy implements BaseImageLoaderStrategy {
private DisplayImageOptions mImageOptions;
/**
* 初始化加載配置
*/
private void initOptions() {
ImageLoaderConfiguration configuration = ImageLoaderConfiguration.createDefault(this);
ImageLoader.getInstance().init(configuration);
mImageOptions = DisplayImageOptions.createSimple();
}
@Override
public void loadImage(Context context, ImageView view, Object imgUrl) {
ImageLoader.getInstance().displayImage(imgUrl, view, mImageOptions);
}
}複製代碼
完成實現類後,最後寫一個調用的工具類就完成了封裝。ide
/**
* 調用圖片框架的工具類
**/
public class ImageLoaderUtils {
private BaseImageLoaderStrategy mImageLoaderStrategy;
private ImageLoaderUtils() {
//默認使用Universal-Image-Loader
mImageLoaderStrategy = new UniversalLoaderStrategy(); }
/**
* 設置圖片框架策略
* @param strategy 圖片框架策略
**/
public static void setImageLoaderStrategy(BaseImageLoaderStrategy strategy) {
if (strategy != null) {
mImageLoaderStrategy = strategy;
}
}
/**
* 調用默認加載圖片
**/
public static void loadImage( Context context, ImageView view, Object imgUrl) {
mImageLoaderStrategy.loadImage(context,view,imgUrl);
}
}複製代碼
到此爲止,就已經完成了初步的封裝,使用方式:工具
ImageLoaderUtils.loadImage(context, imageView, imgUrl);複製代碼
完成了初步封裝,但如何解決框架替換的問題好像還沒說起到。兄弟不要急呀,車如今立刻要開,扶穩了。假如項目如今要使用Glide框架,那咱們須要先寫一個簡單Glide的實現類。以下:
/**
* Glide的實現類
**/
public class GlideLoaderStrategy implements BaseImageLoaderStrategy {
private RequestOptions mOptions;
private ImageLoaderConfig mConfig;
/**
* 初始化加載配置
*/
private RequestOptions getOptions() {
if (mOptions == null) {
mOptions = new RequestOptions();
mOptions.error(mConfig.getErrorPicRes())
.placeholder(mConfig.getPlacePicRes())
//下載的優先級
.priority(Priority.NORMAL)
//緩存策略
.diskCacheStrategy(DiskCacheStrategy.ALL);
}
return mOptions;
}
@Override
public void loadImage(Context context, ImageView view, Object imgUrl) {
with(context)
.load(imgUrl)
.apply(getOptions())
//先加載縮略圖 而後在加載全圖
.thumbnail(Contants.THUMB_SIZE)
.into(view);
}
}複製代碼
搞定了Glide的實現類後,調用ImageLoaderUtils的setImageLoaderStrategy方法便可實現框架的替換,而且不影響其餘代碼。
//切換成Glide框架
ImageLoaderUtils.setImageLoaderStrategy(new GlideLoaderStrategy());複製代碼
主要思想大概就是這樣,但實際項目中的封裝並無這麼簡單,爲了描述這種思想,因此簡單化,在此我貼上源碼地址:https://github.com/fansonq/ImageLoaderUtils,有興趣的讀者不妨下載閱讀,更深的瞭解(源碼有註釋)。
看完圖片框架的封裝,你們不妨嘗試封裝日誌框架進行理解並鞏固,將這種思想融會貫通。
若是這篇文章寫的有錯漏,懇請留言提示糾正;若是有什麼地方描述的不夠清晰,留下評論,我看到會給予回覆,一塊兒交流;若是這篇文章對你有所幫助,不妨點擊「喜歡」給予支持,往後我會努力抽空分享自我以爲不錯的知識點給你們。