마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

뷰페이저 속도개선에 대해서 재질문 드립니다..

0 추천

뷰페이저를 이용해서 (라이브러리  android.support.v4.view.ViewPager 추가)

핸드폰 내의 특정 폴더의 경로를 지정해서 그 안의 모든 이미지들을 보여주고있습니다.

좌우 슬라이드로 넘겨주고, 보여주는 것 까지 ~ 기능은 모두 구현이 되었는데요.

문제가 있습니다. 로딩시간이 꽤 깁니다. 

메인에서 버튼을 누르면 새 액티비티로 전환되면서 뷰페이저로 이미지들을 보여주는데, 

이 이미지가 한 번 뜨는데 2,3초가 걸립니다. 좌우로 슬라이드 하다보면 약간 버벅이는 현상도 있습니다.

이미지의 갯수는 변동됩니다. [고정x] 백개일수도 있고 열개일 수도있는데.. 

이미지 크기도 조금 크다보니 느린 면이있네요.. 백그라운드에서 처리를 해보라는 답변을 받았는데,

어떤식으로 해야하늕는 감이 안옵니다;; 조언 부탁드립니다. (__)

public class Gallary extends Activity {
 
    private ViewPager mPager;
    ImageView image01;
    String path;
    String paths[];
 
     
 
    // Bitmap bm;
    int Gridposition;
    int i;
 
    int maxTexture[];
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallary);
 
        Intent intent = getIntent();
        if (intent != null) {
            path = intent.getStringExtra("path"); // 선택한 path받아옴
                                                             
            paths = intent.getStringArrayExtra("paths");
 
            for (int i = 0; i < paths.length; i++) {
                Log.d("......paths", paths[i]);
            }
            Gridposition = intent.getIntExtra("Gridposition", 0);
            Log.d(".......position", Integer.toString(Gridposition));
        }
        // bm = BitmapFactory.decodeFile(path); //path값으로 비트맵 생성.
        // image01.setImageBitmap(bm);
 
        // 1023 현재 디바이스의 gl max texture size 알아내기
        maxTexture = new int[1];
        GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTexture, 0);
 
        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(new PagerAdapterClass(getApplicationContext()));
        mPager.setCurrentItem(Gridposition);
 
    }// onCreate
 
    private class PagerAdapterClass extends PagerAdapter {
        private LayoutInflater li;
 
        public PagerAdapterClass(Context c) {
            super();
            li = LayoutInflater.from(c);
        }
 
        @Override
        public int getCount() // 뷰페이저 총 갯수
        {
            return paths.length;// 이미지 총 갯수
        }
 
        @Override
        public Object instantiateItem(View container, int position) {
             
            View v = null; // 뷰 생성하기~
         
            for (i = 0; i < paths.length; i++) // 폴더에 있는 이미지 총 갯수만큼!
            {
                if (i == position) 
                {
                     
                    v = li.inflate(R.layout.gallarydetailactivity, null);
                    image01 = (ImageView) v.findViewById(R.id.image01);// 사진띄워줄 imageview
                                                                     
                    Bitmap bm0 = BitmapFactory.decodeFile(paths[i]);
                     
                     
                    Bitmap bm = bm0.createBitmap(bm0, 0, 0, bm0.getWidth(),bm0.getHeight(), m, false);
 
                    int reWidth = (int) (getWindowManager().getDefaultDisplay().getWidth());
                    int reHeight = (int) (getWindowManager().getDefaultDisplay().getHeight());
                    Bitmap reSized = Bitmap.createScaledBitmap(bm, reWidth,reHeight, true);
                    image01.setImageBitmap(reSized);
                     
                    bm0 = null;
                }
            }
 
            ((ViewPager) container).addView(v, 0);
             
            v.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    finish();
                }
            });
            return v;
        }
 
        @Override
        public void destroyItem(View container, int position, Object object) {
            ((ViewPager) container).removeView((View) object);
 
        }
 
        // instantiateItem에서 생성한 객체를 이용할 것이지 여부를 반환.
        @Override
        public boolean isViewFromObject(View pager, Object obj) {
            // TODO Auto-generated method stub
            return pager == obj;
        }
 
        @Override
        public void restoreState(Parcelable state, ClassLoader loader) {
            // TODO Auto-generated method stub
        }
 
        @Override
        public Parcelable saveState() {
            // TODO Auto-generated method stub
            return null;
        }
 
        @Override
        public void startUpdate(View container) // 페이지변경시작
        {
        }
 
        @Override
        public void finishUpdate(View container) // 페이지변경완료
        {
        }
    }
 
     
}

 

anci (19,950 포인트) 님이 2014년 12월 29일 질문

1개의 답변

+1 추천
 
채택된 답변
이미지를 비동기로 불러오는 라이브러리들이 몇가지  있으니 그걸 써보세요

https://github.com/square/picasso

https://github.com/nostra13/Android-Universal-Image-Loader

 

그리고 instantiateItem안에 불필요한 for문 빼시구요
alkyne (22,960 포인트) 님이 2014년 12월 29일 답변
anci님이 2014년 12월 29일 채택됨
댓글 감사합니다.
instantiateItem안의 for문은 제가 불러올 이미지들을 for문으로 반복시켜서 갖고오는건데,  instantiateItem에서 작업하기에 적절하지 않은건가요? 아무래도 이미지 양이 많다보니 for문에서 문제가 있는 것인지..
for문을 돌지만 결국 i == position 일때만 작업을 하게 되니 그냥 position값을 쓰면 되겠지요
댓글감사합니다.
여기저기 참조해보니, 뷰페이저로 띄웠을 때 총 3개의 이미지?를 미리 띄워놓는다고 하더라구요. 이전/현재/다음 이렇게..옆으로 슬라이드할 때 다음 이미지를 미리미리 계속 띄워야 해서 전체 이미지 갯수를 for문으로 돌렸었습니다.
현재 저상태에서 for문을 없애면 당연히 에러가..나구요. 항상 첫번째부터 시작하는게 아니라, 그리드뷰에서 이미지를 선택[position값으로 구별] 해서 보여주는거였습니다.
지금 for (i = position ; i < position+2; i++) 으로 했는데 여전히 느리게 팝업되네요ㅠ
뷰페이저가 미리3개를 준비하긴하지만 그건 뷰페이저가 instantiateItem를 position을 바꿔가면서 3번 부르는거라 별로 상관없는 부분이구요
Bitmap bm0 = BitmapFactory.decodeFile(paths[position]); 이렇게 하란 얘기였습니다. 사실 저 for문은 성능에 크게 영향은 없구요
정작 느리게 만드는것은 이미지처리부분같네요 페이지에 나올 이미지는 하난데 Bitmap객체가 3개나 만들어지고 있죠 특히 리사이즈하는 부분에서 화면 해상도 크기로 리사이즈하는게 가벼운 작업은 아니겠죠 bm0를 바로 이미지뷰에 세팅하시고 이미지뷰의 scaleType을 바꿔줘보세요
아, 그렇군요..지금 alkyne님 조언대로 자료를 찾아보니, 이미지 크기가 적절하지 않게 크거나, 리사이즈할 때에 메모리 문제가 발생한다고 하더군요. 댓글 정말 감사합니다..ㅠㅠ 다시 수정해봐야겠습니다.
+
다른거 건드리지 않고 답변해주신대로 이미지 사이즈를 수정했습니다.
쓸데없이 중복되는 bitmap변수도 3개에서 1개로 줄였구요. 비트맵팩토리 옵션이라는 것중에 insamplesize라고 원본이미지를 1/n으로 축소시켜서 decode시켜주는게 있던데, 이걸로 줄여서 해보니 잘되네요. 정말 답변 감사합니다. 소스상의 문제인줄 알고 봤는데, 이미지크기가 너무 컸던거네요. 지금 원본확인해보니 4300x2200인..;;;
...