1. 程式人生 > >Android 7.0 Gallery相簿原始碼分析8

Android 7.0 Gallery相簿原始碼分析8

Android 7.0 Gallery相簿原始碼分析3 - 資料載入及顯示流程一文最後講了AlbumSetSlidingWindow的onContentChanged方法,專輯縮圖和縮圖下面的label的載入就是在此方法中完成的

    public void onContentChanged(int index) {
        //mData是容量為96的AlbumSetEntry陣列,index是代表載入哪一個專輯,範圍是0-(n-1),n為專輯數
        AlbumSetEntry entry = mData[index % mData.length];
        //專輯縮圖和label主要由下面三個方法完成
updateAlbumSetEntry(entry, index); updateAllImageRequests(); updateTextureUploadQueue(); //onContentChanged方法就是執行mSlotView.invalidate()重新整理介面 if (mListener != null && isActiveSlot(index)) { mListener.onContentChanged(); } }

首先分析updateAlbumSetEntry(entry, index)方法

    private void updateAlbumSetEntry(AlbumSetEntry entry, int slotIndex) {
        ......
        //cover是從專輯裡面獲取的一個圖片,用來作為專輯縮圖
        MediaItem cover = mSource.getCoverItem(slotIndex);
        if (album != null) {
            //AlbumLabelLoader就是用來載入縮圖下面的label,如專輯名、此專輯有多少張圖片等,看引數也能知道
            entry.labelLoader = new
AlbumLabelLoader( slotIndex, title, totalCount, sourceType); } if (cover != null) { //AlbumCoverLoader是用來載入專輯縮圖的載入器 entry.coverLoader = new AlbumCoverLoader(slotIndex, cover); } }

現在載入器都已準備好,下面看載入器是如何載入圖片的,回到onContentChanged方法,看下updateAllImageRequests()方法

    private void updateAllImageRequests() {
        mActiveRequestCount = 0;
        for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) {
            AlbumSetEntry entry = mData[i % mData.length];
            //下面兩句開始執行圖片載入
            if (startLoadBitmap(entry.coverLoader)) ++mActiveRequestCount;
            if (startLoadBitmap(entry.labelLoader)) ++mActiveRequestCount;
        }
        ......
    }

    根據下述程式碼,發現圖片載入最終還是執行Loader的submitBitmapTask()方法
    private static boolean startLoadBitmap(BitmapLoader loader) {
        loader.startLoad();
        return loader.isRequestInProgress();
    }

    public synchronized void startLoad() {
        if (mState == STATE_INIT) {
            mState = STATE_REQUESTED;
            if (mTask == null) mTask = submitBitmapTask(this);
        }
    }

本文只分析專輯縮圖的載入,至於縮圖下面的label請自行檢視程式碼,原理都是一樣的。

下面分析AlbumCoverLoader的submitBitmapTask方法

    protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) {
        //mMediaItem為LocalImage或LocalVideo,下面只分析LocalImage
        return mThreadPool.submit(mMediaItem.requestImage(
            MediaItem.TYPE_MICROTHUMBNAIL), l);
    }

根據上述程式碼可知,縮圖載入是通過執行緒池來完成的。至於此處執行緒池的原理,submit之後會線上程池中執行任務載入縮圖,從ThreadPool的run()方法中知道完成縮圖載入任務後,會呼叫mListener.onFutureDone(this),這裡mListener就是BitmapLoader自身,從future.get中得到Bitmap傳給onLoadComplete(mBitmap)。 之後傳送Handler訊息MSG_UPDATE_ALBUM_ENTRY呼叫AlbumCoverLoader的updateEntry()。

下面分析縮圖是如何載入的,看下LocalImage的程式碼

    //requestImage返回載入Bitmap的Job工作任務,也就是ImageCacheRequest類
    public Job<Bitmap> requestImage(int type) {
        return new LocalImageRequest(mApplication, mPath, dateModifiedInSec,
                type, filePath);
    }

    public static class LocalImageRequest extends ImageCacheRequest {
        private String mLocalFilePath;
        LocalImageRequest(GalleryApp application, Path path, long timeModified,
                int type, String localFilePath) {
            super(application, path, timeModified, type,
                    MediaItem.getTargetSize(type));
            mLocalFilePath = localFilePath;
        }
    }

之後執行緒池會執行此ImageCacheRequest的run方法,完成影象資料的編解碼生成一個Bitmap,這就是所需要的專輯縮圖。至於如何編解碼的,可以檢視ImageCacheRequest的run方法,因為太過複雜,本文就暫時不細講了,後續有時間再講解。

還有一點,這裡只是載入Bitmap,要想將Bitmap顯示到介面上還需要通過AlbumSetSlotRenderer的renderSlot方法來實現。

相關推薦

Android 7.0 Gallery相簿原始碼分析8

在Android 7.0 Gallery相簿原始碼分析3 - 資料載入及顯示流程一文最後講了AlbumSetSlidingWindow的onContentChanged方法,專輯縮圖和縮圖下面的label的載入就是在此方法中完成的 public

Android 7.0 Gallery相簿原始碼分析4

上篇文章講了初始化View時會例項化一個SlotView並監聽其事件,至於它是怎麼實現的,用的是Android自帶的GestureDetector。 GestureDetector是Android自帶的用來監聽各種使用者手勢的的一個類,比如監聽單擊、雙擊和

Android 7.0 Camera架構原始碼分析

Android 7.0之前CameraService是在mediaserver程序中註冊的,看下Android 6.0的程式碼: //path: frameworks\av\media\mediaserver\main_mediaserver.cpp int m

Android 7.0 Gallery圖庫源碼分析4 - SlotView手勢監聽及頁面跳轉

ofo 自帶 end follow mat views mha creat 找到 上篇文章講了初始化View時會實例化一個SlotView並監聽其事件,至於它是怎麽實現的,用的是Android自帶的GestureDetector。 GestureDetector是Andro

Android 7.0 Gallery圖庫源碼分析2 - 分析啟動流程

rec star bject erro argument hold default add 切換 前面一講解了Gallery啟動Activity以及界面如何繪制,現在開始講解啟動流程的代碼邏輯。 GalleryActivity的onCreate方法中調用initialize

Android 7.0 Gallery圖庫源碼分析3 - 數據加載及顯示流程

不為 isempty stat submit mode 準備工作 RKE xtu ida 前面分析Gallery啟動流程時,說了傳給DataManager的data的key是AlbumSetPage.KEY_MEDIA_PATH,value值,是”/combo/{/loca

Android 7.0系統啟動流程分析

隨著Android版本的升級,aosp專案中的程式碼也有了些變化,本文基於Android 7.0分析Android系統啟動流程.當我們按下電源鍵後,整個Android裝置大體經過了一下過程: 今天我們只想來分析init程序及其後的過程,也就是下圖所示部分:

Android 5.0 Camera系統原始碼分析(2):Camera開啟流程

1. 前言 本文將分析android系統原始碼,從frameworks層到hal層,暫不涉及app層和kernel層。由於某些函式比較複雜,在貼出程式碼時會適當對其進行簡化。本文屬於自己對原始碼的總結,僅僅是貫穿程式碼流程,不會深入分析各個細節。歡迎聯絡討論,QQ:1026

Android 7.0 WifiMonitor工作流程分析

在wifi啟動掃描的分析過程中,出現了多次WifiMonitor的操作,在此分析一下這個函式是如何工作的。 在Android的Wifi體系中,WifiMonitor承擔著分發來自wpa_suppli

Android 5.0 Camera系統原始碼分析(4):Camera預覽流程資料流

1. 前言 上一篇講了怎麼讓Camera進入預覽模式,提到了DisplayClient負責顯示影象資料,而CamAdapter負責提供影象資料,這裡主要記錄了CamAdapter怎麼獲取影象,然後DisplayClient怎麼將影象顯示在螢幕上。 2.

Android 5.0 Camera系統原始碼分析(3):Camera預覽流程控制流

1. 前言 本文分析的是Android系統原始碼,從frameworks層到hal層,記錄了Camera進入預覽模式的重點程式碼,主要為控制流程的程式碼,有關影象buffer的傳遞暫不涉及,硬體平臺基於mt6735。由於某些函式比較複雜,在貼出程式碼時會適當對

Android 7.0 分屏原理分析

在以往的Android系統上,所有Activity都是全屏的,如果不設定透明效果,一次只能看到一個Activity介面。 但是從Android N(7.0)版本開始,系統支援了多視窗功能。在有了多視窗支援之後,使用者可以同時開啟和看到多個應用的介面。並且系統還支援在多個

Android 7.0 虛擬按鍵(NavigationBar)原始碼分析 之 View的建立流程

    最近有個需求是修改虛擬按鍵的單擊和長按效果。所以研究了下Android關於虛擬按鍵的實現流程。好記性不如爛筆頭,記錄如下。     首先,幾個重要的類: //實現 單個虛擬按鍵的 自定義ImageView     frameworks/base/packages/

Android SyetemServer程序啟動過程(基於7.0 N版本原始碼)

前言 上一篇我們學習了Zygote程序,並且知道Zygote程序啟動了SyetemServer程序,那麼這一篇我們就來學習Android7.0版本的SyetemServer程序的啟動過程。 1.Zygote啟動SyetemServer程序 在上一篇文章中我們講到在ZygoteInit.j

解決Android 7.0, 8.0手機相機崩潰問題

在android 7.0之後的手機上用以上程式碼開啟相機、相簿會報如下錯誤: android.os.FileUriExposedException: ** exposed beyond app through Intent.getData()  解決方法: 

Android 7.0 startActivity()原始碼解析

本文並不是非常詳細地解釋startActivity()原始碼每行程式碼的具體作用(實際上也根本做不到),所以我省略了很多程式碼,只保留了最核心的程式碼。我研究這段原始碼的目的是解決以下幾個我在開發應用的過程中所思考的問題: 是通過何種方式生成一個新的Activity類的,是

Android SyetemServer程序啟動過程(基於7.0 N版本原始碼)

前言 上一篇我們學習了Zygote程序,並且知道Zygote程序啟動了SyetemServer程序,那麼這一篇我們就來學習Android7.0版本的SyetemServer程序的啟動過程。 1.Zygote啟動SyetemServer程序 在上一篇文章中我們講到在Zyg

Android FrameWork學習(一)Android 7.0系統原始碼下載\編譯

最近計劃著研究下Android 7.0的系統原始碼,之前也沒做過什麼記錄,這次正好將學習的內容記錄下來,方便以後複習鞏固。 既然要學習我們的系統原始碼,那我們第一步要做的就是下載原始碼並進行編譯了。 硬體環境要求 1. 編譯環境 按照官方的說

Android 7.0以上(包含8.0), 或者有虛擬按鍵,popupWindow彈窗位置異常的終極解決方案

問題描述 前段時間發現Popupwindow在8.0的手機上顯示成全屏了,搜了下發現7.0以上就有這個問題了,好久沒寫Popwindow了,才知道(尷尬)。於是總結了在以下情況可能出問題: 當設定PopupWindow 的高度為 MATCH_PARENT,呼叫 showAsD

編譯Android Gallery相簿原始碼所遇bug

1. selectiveAdjust() isnot supported in SDK levels 11-15 Error:(99, 32) error: Non-root compute kernel selectiveAdjust() is no