Android 7.0 Gallery图库源码分析8 - 加载专辑缩略图

作者:lb377463323
出处:http://blog.csdn.net/lb377463323
原文链接:http://blog.csdn.net/lb377463323/article/details/70890461
转载请注明出处!

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源码分析
    原文地址: https://blog.csdn.net/lb377463323/article/details/70890461
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞