`

Android 原生Gallery3d的优化系列--1

 
阅读更多
很久没有更新了,从今天开始来一系列关于Android 原生Gallery3d的学习,优化及问题解决的记录。

当有很多Album存在的时候,快速滑动,会发现需要很久才能显示数据,这是因为在
AlbumSetDataLoader里面的ReloadTask加载数据的时候都是从(mContentStart, mContentEnd)在这个范围内开始加载,而不是优先加载可见的范围(mActiveStart,mActiveEnd)而Google的大神在写这个代码的时候就已经意识到了这点,但没有完成,留下了TODO
// TODO: load active range first

所以找到了问题点,我们就优化先加载[mActiveStart,mActiveEnd]再加载(mContentStart,mActiveStart)和(mActiveEnd,mActiveEnd)

 private int getInvalidIndex(long version) {
            long setVersion[] = mSetVersion;
            int length = setVersion.length;

            //load active range first
            for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) {
                if (setVersion[i % length] != version){
                    return i;
                }
            }

            //load mContentStart ~ mActiveStart
            for (int i = mContentStart; i < mActiveStart; ++i) {
                if (setVersion[i % length] != version){
                    return i;
                }
            }

            //load mActiveEnd ~ mContentEnd
            for (int i = mActiveEnd; i < mContentEnd; ++i) {
                if (setVersion[i % length] != version){
                    return i;
                }
            }
            return INDEX_NONE;
        }

虽然我们上面修改了这里,但在AlbumSetDataLoader里面的mActiveStart和mActiveEnd是没有正确赋值的,所以我们还需要修改AlbumSettSlidingWindow.java中的
 private void setContentWindow(int contentStart, int contentEnd) {
        if (contentStart == mContentStart && contentEnd == mContentEnd){
            return;
        }

        if (contentStart >= mContentEnd || mContentStart >= contentEnd) {
            for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
                freeSlotContent(i);
            }
            mSource.setContentWindow(contentStart, contentEnd);
            for (int i = contentStart; i < contentEnd; ++i) {
                prepareSlotContent(i);
            }
        } else {
            for (int i = mContentStart; i < contentStart; ++i) {
                freeSlotContent(i);
            }
            for (int i = contentEnd, n = mContentEnd; i < n; ++i) {
                freeSlotContent(i);
            }
            mSource.setContentWindow(contentStart, contentEnd);
            for (int i = contentStart, n = mContentStart; i < n; ++i) {
                prepareSlotContent(i);
            }
            for (int i = mContentEnd; i < contentEnd; ++i) {
                prepareSlotContent(i);
            }
        }

        mContentStart = contentStart;
        mContentEnd = contentEnd;
    }

    public void setActiveWindow(int start, int end) {
        if (!(start <= end && end - start <= mData.length && end <= mSize)) {
            Utils.fail("start = %s, end = %s, length = %s, size = %s",
                    start, end, mData.length, mSize);
        }

        AlbumSetEntry data[] = mData;
        mActiveStart = start;
        mActiveEnd = end;
        mSource.setActiveWindow(mActiveStart, mActiveEnd);
        int contentStart = Utils.clamp((start + end) / 2 - data.length / 2,
                0, Math.max(0, mSize - data.length));
        int contentEnd = Math.min(contentStart + data.length, mSize);
        setContentWindow(contentStart,contentEnd);

        if (mIsActive) {
            updateTextureUploadQueue();
            updateAllImageRequests();
        }
    }


也需要在AlbumSetDataLoader修改如下
 public void setContentWindow(int startContent, int endContent) {
        int length = mCoverItem.length;
        // If no data is visible, keep the cache content
        if (startContent == endContent) {
            return;
        }

        int contentStart = Utils.clamp((startContent + endContent) / 2 - length / 2,
                0, Math.max(0, mSize - length));
        int contentEnd = Math.min(contentStart + length, mSize);
        if (mContentStart > startContent || mContentEnd < endContent
                || Math.abs(contentStart - mContentStart) > MIN_LOAD_COUNT) {
            if (contentStart == mContentStart && contentEnd == mContentEnd) {
                return;
            }

            int start = this.mContentStart;
            int end = this.mContentEnd;

            mContentStart = contentStart;
            mContentEnd = contentEnd;

            if (contentStart >= end || start >= contentEnd) {
                for (int i = start; i < end; ++i) {
                    clearSlot(i % length);
                }
            } else {
                for (int i = start; i < contentStart; ++i) {
                    clearSlot(i % length);
                }
                for (int i = contentEnd; i < end; ++i) {
                    clearSlot(i % length);
                }
            }
            mReloadTask.notifyDirty();
        }

    }

    public void setActiveWindow(int start, int end) {
        if (start == mActiveStart && end == mActiveEnd){
            return;
        }

        Utils.assertTrue(start <= end
                && end - start <= mCoverItem.length && end <= mSize);

        mActiveStart = start;
        mActiveEnd = end;


    }


dangAlbumDataLoader同意存在这样的问题,但mActiveStart和mActiveEnd是正常被赋值的,所以只需按照AlbumSetDataLoader要修改第一处getInvalidIndex即可。

此优化和文章由本人实作,若要转载,请标明出处,谢谢!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics