viewPager는 큰 그림 처리와 함께 동적으로 그림을 불러옵니다

6153 단어 viewpager
viewPager는 큰 그림을 동적으로 불러오고 처리합니다.
1. 동적 이미지 로드 수량 실현
그림을 assets 아래에 놓으면 그림의 수량을 동적으로 읽을 수 있으며 그림의 내용과 수량이 바뀔 때 프로그램은 수정할 필요가 없다.
 
 private void initImage(){
	        try {
                pics = this.getResources().getAssets().list("guide");
                LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT);
                
                //         
                for(int i=0; i<pics.length; i++) {
                    ImageView iv = new ImageView(this);
                    iv.setLayoutParams(mParams);
                    GetBitMap.instance().add(this, mHandler,"guide/"+pics[i], UPDATEDATA,iv);
                    views.add(iv);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
	    }

 2.그림이 너무 크면 UI 라인에 놓아서 그림을 읽으면 ANR을 만들기 쉽다. 다음은 비동기 라인에서 그림을 불러오고 그림을 처리하는 방식을 소개한다.
 
다음은 그림을 비동기적으로 불러오는 처리 방식입니다. 하위 라인이 많이 열리지 않습니다.
 
public void add(Context context,Handler handler,String path, int mCode,ImageView imageView){
		BitMapMsg msg = new BitMapMsg();
		msg.mConext = context;
		msg.mHandler = handler;
		msg.path = path;
		msg.mCode = mCode;
		msg.mImgView = imageView;
		mQueue.add(msg);
		if(!running){
		    new Thread(this).start();
		}
	}
	
	public void run() {
		running = true;
		while(mQueue.size() > 0 ){
			BitMapMsg msg = null;
			synchronized (mQueue) {
				msg = mQueue.remove(0);
			}
			if(msg != null && !msg.path.equals("")){
			    Message message = new Message();
                message.what = msg.mCode;
                if(msg.mImgView != null){
                    BitmapData bitmapData = new BitmapData(getBitmap(msg,msg.path),msg.mImgView);
                    message.getData().putParcelable("bitmap", bitmapData);
                    msg.mHandler.sendMessage(message);
                }
			}
		}
		running = false;
	}

3 그림이 너무 크면 그림을 불러올 때 메모리가 넘치는 문제를 겪었다고 믿는다.bitmap을 처리하는 방법을 소개한다.
 
 
가능한 한 setImage Bitmap이나 setImage Resource 또는 Bitmap Factory를 사용하지 마십시오.decode Resource에서 큰 그림을 설정합니다. 이 함수들은 decode를 완성한 후에 최종적으로 자바 층의create Bitmap을 통해 완성되기 때문에 더 많은 메모리를 소모해야 합니다.
따라서 BitmapFactory를 통해decodeStream 방법은bitmap을 만들고 ImageView의source로 설정합니다. decodeStream의 가장 큰 비밀은 JNI>nativeDecodeAsset()을 직접 호출하여 decode를 완성하는 것입니다. 자바층의createBitmap을 사용하지 않아도 자바층의 공간을 절약할 수 있습니다.
만약에 읽을 때 그림의 Config 파라미터를 추가하면 불러오는 메모리를 효과적으로 줄여서 out of Memory 이상을 효과적으로 막을 수 있습니다. 또한 decode Stream이 직접 가져온 그림과 바이트 코드를 읽을 수 있습니다. 기계의 각종 해상도에 따라 자동으로 적응하지 않기 때문에 적당한 문제에 주의하십시오.
 
Config 매개 변수에 대해 살펴보겠습니다.
사실 이것은 모두 색채의 저장 방법이다. 우리는 ARGB가 일종의 색채 모델을 가리킨다는 것을 알고 있다. 그 중에서 A는 알파를 나타내고 R은 레드를 나타내며 G는 그린을 나타내고 B는 블루를 나타낸다. 사실 모든 가시적인 색채는 오른쪽의 빨간색, 녹색, 파란색으로 구성되어 있기 때문에 빨간색, 녹색, 파란색은 삼원색이라고도 부른다. 모든 원색은 표시된 색채의 정보치를 저장하고 있다.
Bitmap.Config  ALPHA_8 도형 매개 변수는 한 바이트로 표시해야 하며 8비트맵 비트맵이어야 한다.Config  ARGB_4444 도형의 매개 변수는 두 바이트로 각각 4개bit로 각 픽셀의 A, R, G, B 데이터를 기록하고 16색 비트맵 비트맵을 표시해야 한다.Config  ARGB_8888 도형의 매개 변수는 각각 8개의bit로 각 픽셀의 A, R, G, B 데이터를 기록해야 한다. 즉, 흔히 말하는 32bit 비트맵, 256색 비트맵(이것도 RGB888과 같은 24bit 비트맵일 수 있다) 비트맵이다.Config  RGB_565 도형의 매개 변수는 두 바이트로 각각 5개, 6개와 5개의bit로 픽셀의 R, G, B 데이터를 기록해야 한다. 그 중에서 G의 6개의bit 중 하나는 무효로 보존된 32색 비트맵이다.
비트맵 자릿수가 높을수록 저장할 수 있는 색상 정보가 많을수록 이미지도 사실적으로 표현됩니다.
 
BitmapFactory에 대해 살펴보겠습니다.Options
적절한 inSampleSize를 설정하는 것이 이 문제를 해결하는 관건 중 하나입니다.BitmapFactory.Options는 다른 구성원인 inJustDecodeBounds를 제공합니다.BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);inJustDecodeBounds를true로 설정하면 decodeFile는 공간을 분배하지 않지만 원시 그림의 길이와 너비, 즉opts를 계산할 수 있습니다.width와opts.height.이 두 개의 매개 변수가 있으면 일정한 알고리즘을 통과하면 적절한 inSampleSize를 얻을 수 있다.Android원본 코드를 보면 Android는 동적 계산 방법을 제공합니다.
 
/**
     *     inSampleSize
     * @param options
     * @param minSideLength
     * @param maxNumOfPixels
     * @return
     */
    public static int computeSampleSize(BitmapFactory.Options options,
            int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength,
                maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options,
            int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
                .sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math
                .floor(w / minSideLength), Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

 

좋은 웹페이지 즐겨찾기