我正在使用自定义滚动视图加载多个图像,如android视图页面。在这个视图中,我已经加载了当前页面,以及我要显示的文档的左,右页面,所以我只使用了三个位图,滚动时由inBitmap选项重用。当我尝试快速更改滚动方向时出现问题。在这种情况下,有时页面的安全性不正确。我很确定这是加载图像的线程的并发问题,但我无法解决它。
搜索其他人发帖,我发现类似的东西[BitmapFactory.Options.inBitmap经常在切换ImageView位图时导致撕裂] [1]
[1]:BitmapFactory.Options.inBitmap causes tearing when switching ImageView bitmap often请帮忙!我的代码:
private static final int WINDOW_SIZE = 3;
private Bitmap mReusableBitmapFront;
private Bitmap mReusableBitmapLeft;
private Bitmap mReusableBitmapRight;
private Bitmap[] mReusableBitmaps = {
mReusableBitmapLeft, mReusableBitmapFront, mReusableBitmapRight
};
private LinearLayout mContentContainer;
private void initPresentationContent() {
for (int page = 0; page < numPages; page++) {
ImageView iView = new ImageView(mContext);
LayoutParams params = new LayoutParams(DEFAULT_WITDH, DEFAULT_HEIGHT);
iView.setLayoutParams(params);
// Init first 3 pages
if (page < WINDOW_SIZE) {
LoadPageAsynTask loadPageTask = new LoadPageAsynTask(page);
loadPageTask.execute();
}
iView.setTag(page);
mContentContainer.addView(iView);
}
}
class LoadPageAsynTask extends AsyncTask<Void, Void, Boolean> {
int mPage;
public LoadPageAsynTask(int page) {
mPage = page;
}
@Override
protected Boolean doInBackground(Void... params) {
String pagePath = CONTENT_PATH + (mPage) + ".jpg";
decodeSampledBitmapFromFile(pagePath, DEFAULT_WITDH, DEFAULT_HEIGHT, mPage % WINDOW_SIZE);
return true;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
// Set page to viewer
((ImageView) mContentContainer.getChildAt(mPage)).setImageBitmap(mReusableBitmaps[mPage
% WINDOW_SIZE]);
}
}
public void decodeSampledBitmapFromFile(String pagePath, int reqWidth,
int reqHeight, int pos) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pagePath, options);
options.inMutable = true;
options.inBitmap = mReusableBitmaps[pos];
options.inSampleSize = 1;
options.inJustDecodeBounds = false;
mReusableBitmaps[pos] = BitmapFactory.decodeFile(pagePath, options);
}
@Override
protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
mCurrentScrollY = scrollY;
mScrollPage = (int) ((scrollY + (mPageHeight * ADVANCE_PAGE_FACTOR))
/ (mContentContainer.getHeight() / numPages));
// Next page
if (mCurrentPage < mScrollPage) {
mCurrentPage = mScrollPage;
if (mContentContainer.getChildAt(mCurrentPage + 1) != null) {
if (((ImageView) mContentContainer.getChildAt(mCurrentPage + 1)).getDrawable() == null) {
LoadPageAsynTask loadPageTask = new LoadPageAsynTask(mCurrentPage + 1);
loadPageTask.execute();
}
}
}
// Previous page
else if (mCurrentPage > mScrollPage) {
mCurrentPage = mScrollPage;
if (mContentContainer.getChildAt(mCurrentPage - 1) != null) {
if (((ImageView) mContentContainer.getChildAt(mCurrentPage - 1)).getDrawable() == null) {
LoadPageAsynTask loadPageTask = new LoadPageAsynTask(mCurrentPage - 1);
loadPageTask.execute();
// Remove unused child
if (mContentContainer.getChildAt(mCurrentPage + (WINDOW_SIZE - 1)) != null) {
Log.d(TAG, "remove child on pos: " + (mCurrentPage + (WINDOW_SIZE - 1)));
((ImageView) mContentContainer.getChildAt(mCurrentPage + (WINDOW_SIZE - 1)))
.setImageDrawable(null);
}
}
}
}
}