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即可。

[color=red]此优化和文章由本人实作,若要转载,请标明出处,谢谢![/color]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值