안드로이드 PhotoView 라이브러리의 OutOfMemory, ViewPager 사용시 좌/우 이동시 문제 및 해결..

이제 안드로이드는 매우 성숙한 플랫폼이 되었다. 이것에 대한 반증으로 안드로이드 앱을 개발하기 위해서 참고할 수 있는 라이브러리가 참 많아졌다. 개인적으로 사진을 보여주기 위해서 전에(2.2 프로요)는 제스처(Gesture)를 사용해서 구현을 했는데, PhotoView 라이브러리를 발견하고는 주로 이 라이브러리를 사용한다. 현재 PhotoView의 master 버전은 OutOfMemory 문제가 있다. 또한 ViewPager와 같이 사용하게 되면 문제가 발생한다.

OutOfMemory가 발생하는 문제는 PhotoViewAttacher의 cleanup 메서드에서 아래의 코드로 해결을 했다.

 
    public final void cleanup() {
        if (null == mImageView) {
            return; // cleanup already done
        }

        final ImageView imageView = mImageView.get();

        if (null != imageView) {
            // Remove this as a global layout listener
            ViewTreeObserver observer = imageView.getViewTreeObserver();
            if (null != observer && observer.isAlive()) {
                observer.removeGlobalOnLayoutListener(this);
            }

            // Remove the ImageView's reference to this
            imageView.setOnTouchListener(null);

            // make sure a pending fling runnable won't be run
            cancelFling();
            
            // 아래 부분 추가로 해결.. 
            Drawable d = imageView.getDrawable();
            if(d != null && d instanceof BitmapDrawable) {
            	Bitmap bm = ((BitmapDrawable)d).getBitmap();
            	if(bm != null)
            		bm.recycle();
            }
        }

        if (null != mGestureDetector) {
            mGestureDetector.setOnDoubleTapListener(null);
        }

        // Clear listeners too
        mMatrixChangeListener = null;
        mPhotoTapListener = null;
        mViewTapListener = null;

        // Finally, clear ImageView
        mImageView = null;
    }

자 다음으로 ViewPager를 사용하면, 아래처럼, 이미지가 잘린 상태로 다음 View가 보이게 된다. 왼쪽이 정상 이미지이고, 오른쪽 화면에서 중간에 잘리 이미지가 보이면서 다음 이미지가 보이게 된다.

PhotoView의 핵심인 PhotoViewAttacher 클래스를 확인해 보면, 아래의 코드를 볼 수 있다. 이 로직이 상위 그룹 즉 ViewPager의 TouchEvent의 Intercept 여부를 결정한다. 코드를 보면, parent 객체와 handled 변수가 false인 경우 Touch 이벤트 처리를 하지 않는다. 하지만, 이렇게 설정을 하게 되면, ViewPager를 사용하는 경우 문제가 생긴다. 스케일 업한 사진이 다 보이기도 전에 ViewPager가 이벤트를 받아서 다음/이전으로 넘어가 버린다.

            if (!handled && null != parent) {
                parent.requestDisallowInterceptTouchEvent(false);
            }

그래서, 소스와 이슈를 확인해 보니, 2013년 10월 27일에 이 이슈가 개발버전에 머지되었다.
머지된 코드는 아래와 같다. master에 이 코드가 머지되어 있지 않아서, 기존의 사용자는 코드레벨에서 아래의 코드를 복사해서 사용해야 문제를 해결할 수 있다.

if (!handled && null != parent && !mAllowParentInterceptOnEdge) {
                parent.requestDisallowInterceptTouchEvent(false);
            }

안드로이드 PhotoView 라이브러리의 OutOfMemory, ViewPager 사용시 좌/우 이동시 문제 및 해결..”에 대한 1개의 생각

  1. mcsongmcsong 글쓴이

    최근에 1.2.3 버전을 릴리즈 하면서 위 문제들이 픽스가 되었습니다.
    그리고, cleanup 메서드에서 Bitmap recycle 메서드 호출은 빠른 메모리 해제를 위해서 필요해 보입니다.

    응답

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.