很久没有更新了,从今天开始来一系列关于Android 原生Gallery3d的学习,优化及问题解决的记录。
当有很多Album存在的时候,快速滑动,会发现需要很久才能显示数据,这是因为在
AlbumSetDataLoader里面的ReloadTask加载数据的时候都是从(mContentStart, mContentEnd)在这个范围内开始加载,而不是优先加载可见的范围(mActiveStart,mActiveEnd)而Google的大神在写这个代码的时候就已经意识到了这点,但没有完成,留下了TODO
// TODO: load active range first
所以找到了问题点,我们就优化先加载[mActiveStart,mActiveEnd]再加载(mContentStart,mActiveStart)和(mActiveEnd,mActiveEnd)
虽然我们上面修改了这里,但在AlbumSetDataLoader里面的mActiveStart和mActiveEnd是没有正确赋值的,所以我们还需要修改AlbumSettSlidingWindow.java中的
也需要在AlbumSetDataLoader修改如下
dangAlbumDataLoader同意存在这样的问题,但mActiveStart和mActiveEnd是正常被赋值的,所以只需按照AlbumSetDataLoader要修改第一处getInvalidIndex即可。
[color=red]此优化和文章由本人实作,若要转载,请标明出处,谢谢![/color]
当有很多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]