Android中使用ImageLoader載入圖片
Android上讓人頭疼的莫過於從網路上獲取圖片,然後顯示圖片,最後還要考慮到圖片的回收問題,這之間只要有任何一個環節有問題都可能直接OOM。尤其在需要展示圖片的列表頁面,會載入大量網路上的圖片,每當快速滑動列表的時候,都會很卡,甚至會因為記憶體溢位而崩潰。
這時就是ImageLoader的 show time
了。ImageLoader的目的是為了實現非同步的網路圖片載入、快取及顯示,支援多執行緒非同步載入。
- ImageLoader的工作原理是這樣的:在顯示圖片的時候,它會先在記憶體中查詢;如果沒有,就去本地查詢;如果還沒有,就開一個新的執行緒去下載這張圖片,下載成功會把圖片同時快取到記憶體和本地。
基於這個原理,我們可以在每一次退出一個頁面的時候,把ImageLoader記憶體中的快取全都清除,這樣就節省了大量記憶體,反正下次再用到的時候從本地再取出來就是了。
此外,由於ImageLoader對圖片是軟引用的形式,所以記憶體中的圖片會在記憶體不足的時候被系統回收(記憶體足夠的時候不會對其進行垃圾回收)。
上面說到了ImageLoader的設計原理,下面來說ImageLoader的使用。
ImageLoader的三大元件:
- ImageLoaderConfiguration——對圖片快取進行總體配置,包挎記憶體快取的大小、本地快取的大小和位置、日誌、下載策略(FIFO還是LIFO)等等。
- ImageLoader——我們一般使用displayImage來把URL對應的圖片顯示在ImageView上。
- ImageLoaderOptions——在每個頁面需要顯示圖片的地方,控制如何顯示的細節,比如指定下載時的預設圖(包括下載中、下載失敗、URL為空等),是否將快取放到記憶體或者本地磁碟。
在這裡,從我正在研讀的一本書上借用一段話描述以上三者的關係。書中的這段話也是引用了部落格園上陳哈哈的博文。原文如下:
===========================================
他們有點像廚房規定、廚師、客戶個人口味之間的關係。ImageLoaderConfiguration就像是廚房裡面的規定,每一個廚師要怎麼著裝,要怎麼保持廚房的乾淨,這是針對每一個廚師都適用的規定,而且不允許個性化改變。ImageLoader就像是具體做菜的廚師,負責具體菜譜的製作。DisplayImageOptions就像是每個客戶的偏好,根據客戶是重口味還是清淡,每一個ImageLoader根據DisplayImageOptions的要求具體執行。
下面就開始給大家講講怎麼使用ImageLoader:
1、重寫application,並初始化配置
public class AppContext extends Application {
/**
* Called when the application is starting, before any activity, service, or
* receiver objects (excluding content providers) have been created.
* (當應用啟動的時候,會在任何activity、Service或者接收器被建立之前呼叫,所以在這裡進行ImageLoader 的配置)
* 當前類需要在清單配置檔案裡面的application下進行name屬性的設定。
*/
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
// 快取圖片的配置,一般通用的配置
initImageLoader(getApplicationContext());
}
private void initImageLoader(Context context) {
// TODO Auto-generated method stub
// 建立DisplayImageOptions物件
DisplayImageOptions defaulOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true).cacheOnDisk(true).build();
// 建立ImageLoaderConfiguration物件
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(
context).defaultDisplayImageOptions(defaulOptions)
.threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.diskCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO).build();
// ImageLoader物件的配置
ImageLoader.getInstance().init(configuration);
}
}
在使用ImageLoader的例項之前,你需要初始化該配置,否則會報初始化錯誤。一般我們直接寫在application中初始化。
在初始化配置完成後,在清單配置檔案中寫入你自定義的application,並寫入訪問許可權。如下圖所示:
到這裡基本的配置就完了,接下來就是載入圖片了。
2、在使用ImageView載入圖片的地方,配置當前頁面的ImageLoader選項。有可能是Activity,也有可能是Adapter。我這個demo是在adapter裡面配置DisplayImageOptions物件。程式碼如下所示:
public class MainActivity extends Activity {
// 建立ImageLoader物件
private ImageLoader imageLoader = ImageLoader.getInstance();
private ListView lsv_image_loader;
// 網路圖片的URL和drawable下的圖片,其他的圖片(比如手機本地)的URL看我部落格有寫,這裡沒有全部給出,大家可以自己去試試看。
private String[] picture_uri = new String[] {
"http://pic2.16pic.com/00/15/80/16pic_1580359_b.jpg",
"http://pic.58pic.com/58pic/14/21/47/26t58PICywd_1024.jpg",
"http://pic.58pic.com/58pic/14/21/42/15T58PICe3i_1024.jpg",
"http://pic.58pic.com/58pic/14/21/44/52758PICtw2_1024.jpg",
"http://pic.58pic.com/58pic/14/21/32/81U58PICJqm_1024.jpg",
"http://pic.58pic.com/58pic/14/21/37/46B58PICudW_1024.jpg",
"http://pic.58pic.com/58pic/14/21/39/72g58PICd3K_1024.jpg",
"http://img15.3lian.com/2015/f3/08/d/02.jpg",
"http://pic.58pic.com/58pic/14/21/47/99N58PICE7q_1024.jpg",
"drawable://" + R.drawable.png_11 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 設定該Activity使用的佈局檔案
setContentView(R.layout.activity_main);
// 獲取ListView控制元件
lsv_image_loader = (ListView) findViewById(R.id.lsv_image_loader);
// 建立ImageLoaderBaseAdapter物件
ImageLoaderBaseAdapter adapter = new ImageLoaderBaseAdapter(this);
// listView設定adapter
lsv_image_loader.setAdapter(adapter);
}
/**
* 自定義ImageLoaderBaseAdapter繼承BaseAdapter,重寫相關方法
* @author 鄒奇
*
*/
class ImageLoaderBaseAdapter extends BaseAdapter {
private LayoutInflater inflater;
public ImageLoaderBaseAdapter(Context context) {
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return picture_uri.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return picture_uri[position];
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.lsv_item_image_loader,
null);
holder = new ViewHolder();
holder.iv_lin = (ImageView) convertView
.findViewById(R.id.iv_lin);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
// 建立DisplayImageOptions物件並進行相關選項配置
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)// 設定圖片下載期間顯示的圖片
.showImageForEmptyUri(R.drawable.ic_launcher)// 設定圖片Uri為空或是錯誤的時候顯示的圖片
.showImageOnFail(R.drawable.ic_launcher)// 設定圖片載入或解碼過程中發生錯誤顯示的圖片
.cacheInMemory(true)// 設定下載的圖片是否快取在記憶體中
.cacheOnDisk(true)// 設定下載的圖片是否快取在SD卡中
.displayer(new RoundedBitmapDisplayer(20))// 設定成圓角圖片
.build();// 建立DisplayImageOptions物件
// 使用ImageLoader載入圖片
imageLoader.displayImage(picture_uri[position],
holder.iv_lin, options);
return convertView;
}
/**
* 控制元件快取類
* @author 鄒奇
*
*/
class ViewHolder {
ImageView iv_lin;
}
}
@Override
protected void onDestroy() {
// 回收該頁面快取在記憶體中的圖片
imageLoader.clearMemoryCache();
super.onDestroy();
}
}
上面的程式碼中我都給出了註釋,方便大家理解。這裡我給出的是網路上的圖片的URL和drawable下的圖片的URL,比如上面的ImageLoaderBaseAdapter 裡,使用ImageLoader物件載入圖片的方法如下:
imageLoader.displayImage(picture_uri[position],holder.iv_lin, options);// ImageLoader物件利用圖片的URL載入圖片
其中displayImage方法的第一個引數是圖片的URL,第二個引數是ImageView控制元件。
一般來說,ImageLoader效能如果有問題,就和這裡的配置有關,尤其是ImageLoaderConfiguration。而這裡上面的一些配置程式碼都是目前比較通用的,大家可以參考。
最後給大家講講ImageLoader的優化吧!這是我現在正在研讀的一本書上面提到的,這裡分享給大家。原文如下:
===========================================
儘管ImageLoader很強大,但一直把圖片快取在記憶體中,會導致記憶體佔用過高。雖然對圖片的引用是軟引用,軟引用在記憶體不夠的時候會被GC,但我們還是希望減少GC的次數,所以要經常手動清理ImageLoader中的快取。
我們在上面MainActivity的 onDestroy()生命週期方法中,執行了ImageLoader的clearMemoryCache方法,以確保頁面銷燬時,把為了顯示這個頁面而增加的記憶體快取清除。這樣,即使到了下個頁面要複用之前載入過的圖片,雖然記憶體中沒有了,根據ImageLoader的快取策略,還是可以在本地磁碟上找到:
@Override
protected void onDestroy() {
// 回收該頁面快取在記憶體中的圖片
imageLoader.clearMemoryCache();
super.onDestroy();
}
這裡載入圖片時候,寫圖片的URL的時候需要注意,圖片的URL可以分為以下幾種:
// 網路圖片
String imageUri = "http://pic2.16pic.com/00/15/80/16pic_1580359_b.jpg";
//SD卡圖片
String imageUri = "file:///mnt/sdcard/zouqi.png";
// 媒體資料夾
String imageUri = "content://media/external/audio/albumart/6";
// assets
String imageUri = "assets://zouqi.png";
// drawable檔案
String imageUri = "drawable://" + R.drawable.zouqi;
好了,所有的配置和方法都講完了。下面給大家演示一下載入的圖片效果:
listView的第一張圖片
listView的第二張圖片
listView的第三張圖片
listView的最後一張圖片,最後的小狗圖片是drawable下的圖片資源
- 這裡我寫的demo只加載了網路的和drawable下的圖片,其他的圖片載入大家就自己去試試看,其實就是URL的寫法,這裡就不過多講了,上面有講到。最後大家別忘了給清單配置檔案加網路許可權和寫許可權:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
ImageLoader的jar包資源:點我下載
載入圖片的Demo:點我下載
每天進步一點點!加油!
相關推薦
Android中使用ImageLoader載入圖片
Android上讓人頭疼的莫過於從網路上獲取圖片,然後顯示圖片,最後還要考慮到圖片的回收問題,這之間只要有任何一個環節有問題都可能直接OOM。尤其在需要展示圖片的列表頁面,會載入大量網路上的圖片,每當快速滑動列表的時候,都會很卡,甚至會因為記憶體溢位而崩潰。
Android中WebView載入Html中的圖片新增點選事件
基本的思路: (1)WebView來載入HTML。 (2)向HTML中注入JavaScript,利用JavaScript來呼叫Android中的方法(執行一些跳轉的操作等等)。 首先你必須有一個HTML或者是一個地址,或者是存到本地的一個檔案。我這裡使用的是存到本
Android 通過RGB_565載入圖片在記憶體中佔用大小
我有一張 420*210 的png圖片,放在assets 目錄下。通過如下方式載入到記憶體中: BitmapFactory.Options options =new BitmapFactory.Options(); options.inPreferredConfig = B
在列表中,ImageLoader載入圖片可以通過此方法讓其延遲載入
ListView來顯示大量的圖片,而當我們快速滑動GridView,ListView,我們希望能停止圖片的載入,而在GridView,ListView停止滑動的時候載入當前介面的圖片ImageLoad
android開發ImageLoader網路圖片載入簡單使用
Android上最讓人頭疼的莫過於從網路獲取圖片、顯示、回收,任何一個環節有問題都可能直接OOM,這個專案或許能幫到你。Universal Image Loader for Android的目的是為了實現非同步的網路圖片載入、快取及顯示,支援多執行緒非同步載入。它最
Android中處理大圖片時圖片壓縮
oca 內存空間 pan std ret bitmap sans source tar 1、BitmapFactory.Options中的屬性 在進行圖片壓縮時,是通過設置BitmapFactory.Options的一些值來改變圖片的屬性的,以下我們來看看BitmapF
在android中畫圓形圖片的幾種辦法
http hub image art 鋸齒 tar ets oid tex 在開發中常常會有一些需求,比方顯示頭像,顯示一些特殊的需求,將圖片顯示成圓角或者圓形或者其它的一些形狀。可是往往我們手上的圖片或者從server獲取到的圖片都是方形的。這時候就須要我們自
Android中ViewPager載入空白
記錄一個bug 現象: viewpager載入空白 我的佈局是MainActivity裡面主頁面是5個fragment,然後在MainActivity裡面還有一個側邊欄DrawLayout,其中我想在DrawLayout的佈局中是一個Tablayout+ViewPager+Fragm
《ImageLoader載入圖片》
ImageLoader載入圖片 1主佈局 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android=“http://sche
ImageLoader載入圖片
1.建立一個App繼承Application(APP的頁面) //優先於所有頁面(Activity)建立 //主要負責應用全域性初始化 //該物件也是一個context public class App extends Application { @Override public
Android中一張圖片佔據的記憶體大小是如何計算
最近封裝了個高斯模糊元件,正好將圖片相關的理論基礎也梳理了下,所以,這次就來講講,在 Android 中,怎麼計算一張圖片在記憶體中佔據的大小,如果要優化,可以從哪些方向著手。 提問 閱讀本篇之前,先來想一些問題: Q1:一張 png 格式的圖片,圖片檔案大小為 55.8KB,那麼它載入進記憶體時所佔的大小是
【轉】Qml中Image載入圖片再不同平臺的方式
今天用QML中Image載入win系統下的本地路徑圖片的時候, 發現無論加絕對路徑或file://+path都打不開,就很奇怪,經過一番 查閱發現,各個系統的載入方式都不相同, win系統: Image { id: preview
Android 中 資原始檔圖片轉 Bitmap 和 Drawable 以及相互轉換的方法
Android 圖片轉換的方法總結: 一、Bitmap 轉換成 Drawable 對 Bitmap 進行強制轉換 Drawable drawable = new BitmapDrawable(bmp); 二、Drawable 轉換成 Bitmap 方法一 通過 BitmapFa
webView--Android中webView載入H5時,H5頁面在不同的手機可能出現文字或者圖示類似換行的現象
@Override public Resources getResources() { Resources res = super.getResources(); Configuration config=new Configuration(); config.setToDefaults(); res.up
列表中Glide載入圖片大小顯示不正常問題
Glide載入圖片時大時小 前言:最近在專案中發現了一個奇怪的現象,在列表的item佈局中使用了glide來載入網路圖片,奇怪的現象出現了…同一張圖,同一份資料,有的時候顯示正常,有的時候該圖片顯示出來會稍微小一圈… 解決辦法:百思不得其解,找了很多資料,以為對recyclervie
Android 中關於載入Bitmap知識點
在安卓開發中遇到載入圖片是很平常的事情,圖片即bitmap,但是Android對於每一個應用程式只分配了16M的記憶體空間,所以在載入比較大點的bitmap的時候很容易,會出現OOM異常。 android 中載入圖片的類BitmapFactary,提供了四類方法:decodeS
android中動態載入webview,webview載入html資料,並且隱藏滾動條
ScrollView layouts = (ScrollView) findViewById(R.id.web); WebView webviews = new WebView(DtDetailActivity.this);webviews.setVisibility(
Android中如何編寫圖片選擇器,實現按點選按鈕時按鈕的圖片或者顏色發生變化
1. 先看個圖,展示下我們要實現的效果:,點選按鈕的時候,按鈕變為這種顯示效果。 2. 其實這就是個圖片選擇器的編寫,當按鈕點選的時候,用另一張圖片去替換原有圖片,實現顏色的變化。 3. 具體步驟: (1)首先在應用程式下→res目錄下建立一個folder,命名為d
Android中為網路圖片設定高斯模糊效果
寫一個方法,用來對Bitmap進行高斯模糊: public static Bitmap blurBitmap(Bitmap bitmap ,Context context){ //Let
android 使用Glide載入圖片閃動問題
1、RecyclerView 有自己預設的動畫,去除預設動畫 ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); 並且設定對應的adapter,