前言:
? ? ? ? ?在我剛剛完成的一個版本開發(fā)中太抓,有這樣的一個需求,我們選擇了多個視頻,進入到下面幾個層級的時候铺厨,需要把視頻文件的第一幀圖片展示在imageview上缎玫,對視頻做處理硬纤,在這個地方,怎樣把視頻第一幀圖像很快的取出來赃磨,就有了這篇文章筝家,以記錄開發(fā)中的點點滴滴,下面開始介紹邻辉。 ?
? ? ? ? ?1.場景設(shè)置為讀取手機的視頻文件溪王,gridview顯示視頻第一幀,顯示的速率不能太慢了值骇,選擇多個視頻莹菱,進入到第二層界面,界面要非持ù瘢快顯示出視頻的封面道伟。
? ? ? ? 2.now let's do it,首先第一步在項目的AndroidManifest清單文件中添加上讀取權(quán)限
? ? ? 3.第二步先獲出來的所有的視頻文件使碾,所以先定義視頻文件bean對象MediaModeVideo蜜徽,一個視頻文件的name,文件fileUrl,視頻文件時長票摇,現(xiàn)在定義單個的文件夾對象VideoPhotoFloder,這個對象我包含了視頻和圖片的集合對象拘鞋,但是這里我們只需要視頻集合。
? ? ? ?3.第三步獲取手機里面的視頻文件矢门,有了對象了盆色,那還會單身嗎,哈哈??祟剔,寫一個util工具類獲取全部的視頻文件分文件夾都取出來隔躲,別忘了在界面打開的時候申請權(quán)限,不然就尷尬了峡扩,說什么都不如代碼實在蹭越。
? ? 獲取視頻的方法是調(diào)用Android 內(nèi)容解析器ContentResolver,查詢的5個參數(shù)uri教届,projection响鹃,selection驾霜,selectionArgs,sortOrder买置,具體5個參數(shù)的用處就自行學(xué)習吧》嗖冢現(xiàn)在方法已經(jīng)有了,可以拿到數(shù)據(jù)了忿项,界面上的繪畫就比較簡單了蓉冈,一個簡單的gridview,調(diào)用我們的util的獲取方法設(shè)置適配器就完事
? ? ? 為了讓其他界面能快速的拿到視頻對象的第一幀,在這個適配器的里面就是我們要重點說的地方轩触。在adapter里面對視頻文件根據(jù)地址異步獲取第一幀做緩存寞酿,就是為了在后面的操作中可以快速的獲取到視頻的封面。
還是不說廢話上代碼脱柱,繼承AsyncTask伐弹,定義一次執(zhí)行線程數(shù)量最多10個個線程,
? ? ? ?因為我們定義了視頻和圖片兩種類型或者加了type類型作為BLGalleryCache讀取的條件之一
? 我在異步處理中分配給自己做的緩存BLGalleryCache大小是進程內(nèi)存的1/8榨为,BLGalleryRetainCache一個單例類保證BLGalleryCache單例惨好,好了現(xiàn)在就介紹BLGalleryCache的作用,
? ? ? ? 緩存主要用的是LruCache,LruCache是android提供的一個緩存工具類随闺,其算法是最近最少使用算法日川。它把最近使用的對象用“強引用”存儲在LinkedHashMap中,并且把最近最少使用的對象在緩存值達到預(yù)設(shè)定值之前就從內(nèi)存中移除矩乐,就是醬紫??龄句,在adapter中單個new 出來的時候,從單例中獲取到mBitmapCache根據(jù)key取對應(yīng)的bitmap.在LruCache清理掉的時候绰精,開個AsyncTask再去取撒璧。
可以看到我設(shè)置了一個條件當不是在滑動的時候才去加載,在Scrolling的時候是沒有執(zhí)行task的笨使,這樣也只是為了不損耗資源吧卿樱。好了,最后一步了硫椰,在mBitmapCache里面沒有或者被清理的時候繁调,去AsyncTask地址Url獲取bitmap
private classBLBitmapLoaderTaskextendsAsyncTask {
privateBaseAdaptermAdapter;
privateStringmImageKey;
publicBLBitmapLoaderTask(String imageKey,BaseAdapter adapter) {
mAdapter= adapter;
mImageKey= imageKey;
}
@Override
protected voidonPreExecute() {
mCurrentTasks.add(mImageKey);
}
@Override
protectedBitmapdoInBackground(Void... params) {
Bitmap bitmap =null;
try{
bitmap = ThumbnailUtils.createVideoThumbnail(mImageKey,
Thumbnails.FULL_SCREEN_KIND);
if(bitmap !=null) {
bitmap = Bitmap.createScaledBitmap(bitmap,mMaxWidth,
mMaxWidth, false);
addBitmapToCache(mImageKey,bitmap);
returnbitmap;
}
return null;
}catch(Exception e) {
if(e !=null) {
e.printStackTrace();
}
return null;
}
}
@Override
protected voidonPostExecute(Bitmap param) {
mCurrentTasks.remove(mImageKey);
if(param !=null) {
if(mAdapter!=null)
mAdapter.notifyDataSetChanged();
}
}
}
直接上代碼了,傳遞adapter過來是為了讓界面刷新靶草,imageview是adapter里面調(diào)用的時候傳遞的holder .image.到此為止蹄胰,我們的緩存就搞出來了,核心就是利用LruCache其特性做這件事奕翔。好處就是什么呢裕寨,好處就是在我很深層級的地方,只要一個視頻的地址就可以輕松拿到bitmap。渲染速率宾袜,自然非衬硌蓿快,也完美的完成了項目的需求庆猫。需要調(diào)用的地方就是簡單的一行代碼搞定
代碼鏈接后面會附上∪瞎欤現(xiàn)在看下場景運行的效果
? ? 因為限制10M,所以壓縮的挺厲害的月培,有些失真了嘁字,感謝大家的閱讀,希望對大家有一點點的促進杉畜,代碼會托管到git上纪蜒,鏈接隨后附上。