2013-04-24 4 views
4

보드 게임을 만들고 있고 보드에 10x10 GridView를 사용하고 있습니다. 나는 Integer 배열의 아이콘 (9 패치 파일)을 보유하는 BaseAdapter 클래스를 확장 한 클래스 ImageAdapter를 만들었으며, 보드의 사각형에 대한 이미지를 표시하는 데 사용됩니다. 아이콘은 res/drawable 폴더에 저장되며 크기는 629X629이며 평균 크기는 약 5KB입니다.메모리 부족합니다. setImageResource에서 오류가 발생했습니다.

편집 :

내 ImageAdapter 클래스는 기본적으로 메모리를 저장하기 위해 동일한보기를 재활용 다음의 getView() 메소드를 가지고있다 (필자는 게임 활동에서 호출되는 changeIcon 방법을 포함 시켰습니다)

public View getView(int position, View convertView, ViewGroup parent) { 
    ImageView imageView; 
    if (convertView == null) { // if it's not recycled, initialize some attributes 
     imageView = new ImageView(mContext); 
     imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 
     imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
     imageView.setPadding(8, 8, 8, 8); 
    } 
    else{ 
     imageView = (ImageView) convertView; 
    } 


    imageView.setImageResource(mThumbIds[position]); 
    return imageView; 
} 

public void changeIcon(int x, int y, Integer icon){ 
    int position = (9-y)*10 + x; 
    mThumbIds[position] = icon; 
    getView(position, currentView, null); 
} 

나는 게임의 논리가 처리되는 게임이라는 별도의 클래스가 있습니다. 나는 Piece가 게임의 조각들을 (당신이 짐작 한) 데이터를 저장하기 위해 만든 또 다른 클래스 인 Piece [] [] 배열에 조각들을 저장합니다. 관련성이있는 방법은 조각의 움직임을 처리하는 move (int xFrom, int yFrom, int xTo, int yTo)입니다. 나는 하루 종일 조각을 움직일 수 있고 모든 것이 좋습니다.

그러나 한 번 이동하면 으로 앱이 충돌합니다. 의도 한 동작은 새로운 조각이 생성된다는 것입니다. 이 문제가 발생하는 코드는 다음과 같습니다.

public boolean move(int xFrom, int yFrom, int xTo, int yTo){ 

    boolean success = false; 
    Piece pieceToMove = getPiece(xFrom,yFrom); 
    Piece pieceAtDest = getPiece(xTo,yTo); 
    int moveTeam = pieceToMove.getTeam(); 

    if(isLegalMove(xFrom, yFrom, xTo, yTo, pieceToMove)&&(turn == moveTeam)){ 
     if(pieceAtDest == null) 
     { 
      /*I do something when the destination piece is null; 
         this block causes no problems */ 
     } 
     else{ 
      success = true; 
      pieceToMove.merge(); 
      position[xTo][yTo] = pieceToMove; 
      position[xFrom][yFrom] = null; 
     } 
    } 
    return success; 
} 

따라서 불쾌한 호출은 pieceToMove.merge()입니다. Piece 클래스의 merge() 메서드는 해당 클래스의 유형 필드를 변경하기 만합니다. 그러면 해당 클래스의 setIcon() 메서드가 호출됩니다. 이 메서드는 type 값에 따라 아이콘 필드를 클래스의 필드로 설정합니다. 그리고 위에서 언급했듯이 아이콘은 res/drawable에있는 9 개의 패치 파일을 참조하는 정수입니다.

마지막으로, 방법의 이동이 (INT xFrom, INT yFrom, INT XTO, INT YTO) 활동 GameBoardActivity에서 호출, 성공적인 몸놀림으로 활동 보드를 다시 그리기 (어댑터라고도 함) ImageAdapter를 요청하고, 다음과 같이

boolean success = game.move(xFrom,yFrom,xTo,yTo); 

if(success){ 

Integer destIcon = game.getPiece(xTo, yTo).getIcon(); 
Piece pieceAtDep = game.getPiece(xFrom, yFrom); 
Integer depIcon; 
if(pieceAtDep == null) 
    depIcon = R.drawable.square; 
else 
    depIcon = game.getPiece(xFrom, yFrom).getIcon(); 
adapter.changeIcon(xTo,yTo,destIcon); 
adapter.changeIcon(xFrom,yFrom,depIcon); 
gridView.setAdapter(adapter); 
} 

를 로그 캣 라인이 "치명적인 신호 (11)"에 선행 및 "메모리에서 해제 6,330,272 바이트 할당을"ImageAdapter의의 getView 방법에서 광고 imageView.setImageResource(mThumbIds[position]); 것을 말한다.

두 조각을 병합 할 때까지 모든 것이 잘 돌아갑니다. 그런 다음 메모리 부족 오류가 발생합니다. 이 병합 동작이 이전의 앱 반복에서 완벽하게 작동하고 있다는 점도 유의할 필요가 있습니다.

Java/Android에서 코딩 할 때 완전한 초보자라는 점에 대해 표준 면책 조항을 언급해야하며 유사한 문제와 관련된 다른 질문을 살펴 보았지만 다른 누구도 해당 비트 맵을 처리하지 않는 것 같습니다. 나도 마찬가지야.

도움을 주시면 대단히 감사하겠습니다. 대단히 감사합니다.

UPDATE 가끔 문제가 발생하고, 때로는하지, 나는 어떤 경우가 아닌 다른 사람의 충돌의 원인을 식별 할 수 있다는 또 다른 이상한 나타났습니다 더 테스트를 통해

. 더 정확하게 말하면, 똑같은 이동 순서를 수행하면 충돌이 발생할 수도 있고 그렇지 않을 수도 있습니다. 이것은 아주 신비합니다.

+0

이미지보기를하기 전에 ** 엄지 손가락 **을 만들어야합니다. –

+0

mThumbIds를 의미합니까? 이전에 생성되었지만 코드 스 니펫에는 포함되지 않았습니다. – Rookatu

+0

이미지 자체에 대한 실제 참조가 만들어 져야한다는 것을 의미하는 경우, 나는 changeIcon 메서드를 포함 시켰습니다. GameBoardActivity에서 호출됩니다. – Rookatu

답변

6

코드 mThumbIds입니다. 드로어 :입니다. 당신이해야 할 일은 다음 코드로 엄지 손가락 특정 이미지를 만들어야한다는 것입니다.

public static int calculateInSampleSize(BitmapFactory.Options options, 
     int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     // Calculate ratios of height and width to requested height and 
     // width 
     final int heightRatio = Math.round((float) height 
       /(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will 
     // guarantee 
     // a final image with both dimensions larger than or equal to the 
     // requested height and width. 
     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
    } 

    return inSampleSize; 
} 

public static Bitmap decodeSampledBitmapFromResource(Resources res, 
     int resId, int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(res, resId, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, 
      reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeResource(res, resId, options); 
} 

사용이 코드, 여기

decodeSampledBitmapFromResource(getResources(),R.drawable.xyz, 100, 100); 

, 100 * 100 샘플 크기 당신이 제공하고 있습니다. 그래서 같은 크기의 썸네일이 생성됩니다.

+1

그것은 매력처럼 작동했습니다! 감사합니다 100 Chintan! 비트 맵의 ​​크기가 줄어들고 있지만 이해할 수없는 메모리에 문제가 있습니까? 스크린에 물건을 더 넣을 때이 문제가 다시 발생합니까? 그리고 그 문제는 왜 가끔씩 만 발생합니까? – Rookatu

+0

** Bitmap **을 사용하는 동안 ** SoftReference ** 또는 ** WeakReference **를 사용할 수 있지만 ** null **을 반환하는 경우가 있으므로이 예제에서는 제안하지 않겠습니다. 그러나 비트 맵을 생성하는 동안 이것을 사용할 수 있으며 어떤 작업을 수행 한 후에도 필요하지 않습니다. –

+1

잘 작동합니다 .. thanks buddy – chiru

관련 문제