-1

간단한 Android 게임을 개발하고 있지만 테스트하는 동안 문제가 있습니다. Lenovo Tab3 7 tablet (Android 5.0.1) 또는 LG P880 phone (Android 4.0.3)에서 실행하면 정상적으로 작동합니다. 내가 삼성 S7 휴대 전화 (안드로이드 7.0) 게임을 실행할 때 일반적으로 잘 실행됩니다. 내가 의미하는 바는 내가 문제없이 10 번 연속으로 실행할 수 있지만 때로는 게임이 5-30 초 동안 멈추거나 응답을 멈추는 경우입니다. 이것은 대개 새로운 활동을 시작하거나 그 직후에 발생합니다.단순한 게임은 태블릿에서 작동하지만 때로는 휴대 전화에 뒤쳐집니다.

게임의 레이아웃은 확장 SurfaceView 인 4 Activities입니다. 모든 SurfaceViews는 Runnable을 구현합니다. 활동은 다음과 같습니다. 스플래시 화면 (noHistory = Manifest의 "true"), 메뉴, 난이도 선택 및 게임.

나는 mdpi drawables 만 사용하고 모든 화면 크기에 비례하여 크기를 조정합니다. 비트 맵은 BitmapFactory.decodeResource을 사용하여 BitmapFactory.OptionsinDensity = 1, inScaled = false으로로드됩니다.

문제가 발생하면 logcat은 가비지 수집 만 표시합니다. 때로는 게임이 5 ~ 30 초 동안 "일시 중지"(아무런 탭도 등록되지 않음) 정상적으로 재개됩니다. 응답이 없기 때문에 게임을 다시 시작해야하는 경우가 있습니다. 나는 게임이 어떤 이유로 입력을 수집하지 않는 것처럼 느낍니다. 입력은 onTouchEvent을 무시하고 ACTION_UP이 탭 이미지 경계 내에 있는지 확인하여 처리됩니다. 제가 말했듯이, 이것은 태블릿이나 P880이 아닌 S7 (두 대의 전화기에서 시험해 보았을 때)에서만 발생합니다. 따라서 Nougat 또는 전화에서 density과 강제로 연관 될 수 있습니다.

안드로이드 게임 개발에 새로운 아이디어가 될 수있는 아이디어가 부족하기 때문에 솔루션을 찾고자하는 사람이 누구인지 알고 있습니다. 어떤 노가트 특유의 설정/점검을해야합니까? 강제로 픽셀 밀도가 어떤 식 으로든 장치 성능에 영향을 줍니까?

편집 1

globalApp

public class globalApp extends Application { 
SoundPool soundPool; 
SoundPool.Builder soundPoolBuilder; 

AudioAttributes audioAttributes; 
AudioAttributes.Builder audioAttributesBuilder; 

int soundTap, soundCorrect, soundIncorrect, soundVictory, soundDefeat; 
int soundBarrelVerySlow, soundBarrelSlow, soundBarrelNormal, soundBarrelFast, soundBarrelVeryFast; 

@Override 
public void onCreate() { 
    super.onCreate(); 

} 

public void buildSoundPool(){ 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     audioAttributesBuilder = new AudioAttributes.Builder(); 
     audioAttributesBuilder.setUsage(AudioAttributes.USAGE_GAME); 
     audioAttributesBuilder.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION); 
     audioAttributes = audioAttributesBuilder.build(); 

     soundPoolBuilder = new SoundPool.Builder(); 
     soundPoolBuilder.setMaxStreams(2); 
     soundPoolBuilder.setAudioAttributes(audioAttributes); 
     soundPool = soundPoolBuilder.build(); 
    } 
    else { 
     soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); 
    } 
} 

public void loadSounds(){ 
    soundBarrelVerySlow = soundPool.load(this,R.raw.very_slow_move, 1); 
    soundBarrelSlow = soundPool.load(this, R.raw.slow_move, 1); 
    soundBarrelNormal = soundPool.load(this, R.raw.slow_move, 1); 
    soundBarrelFast = soundPool.load(this,R.raw.fast_move, 1); 
    soundBarrelVeryFast = soundPool.load(this,R.raw.very_fast_move, 1); 
    soundTap = soundPool.load(this, R.raw.tap_sound, 1); 
    soundCorrect = soundPool.load(this, R.raw.correct, 1); 
    soundIncorrect = soundPool.load(this, R.raw.incorrect, 1); 
    soundVictory = soundPool.load(this, R.raw.victory, 1); 
    soundDefeat = soundPool.load(this, R.raw.defeat, 1); 
} 

public void playTap(){ 
    soundPool.play(soundTap, 1, 1,1, 0, 1); 
} 

public void playCorrect(){ 
    soundPool.play(soundCorrect, 1, 1,1, 0, 1); 
} 

public void playIncorrect(){ 
    soundPool.play(soundIncorrect, 1, 1,1, 0, 1); 
} 

public void playVictory(){ 
    soundPool.play(soundVictory, 1, 1,1, 0, 1); 
} 

public void playDefeat(){ 
    soundPool.play(soundDefeat, 1, 1,1, 0, 1); 
} 

public void playBarrelVerySlow(){soundPool.play(soundBarrelVerySlow, 1, 1, 1, 0, 1);} 

public void playBarrelSlow(){soundPool.play(soundBarrelSlow, 1, 1, 1, 0, 1);} 

public void playBarrelNormal(){ 
    soundPool.play(soundBarrelNormal, 1, 1,1, 0, 1); 
} 

public void playBarrelFast(){soundPool.play(soundBarrelFast, 1, 1, 1, 0, 1);} 

public void playBarrelVeryFast(){soundPool.play(soundBarrelVeryFast, 1, 1, 1, 0, 1);} 
} 

의 MenuItem

public class MenuItem { 
private Bitmap bmp; 
private Context context; 

private Rect sourceRect; 
private RectF destRect; 

private int srcWidth; 
private int srcHeight; 

private int destW, destH; 

private int x, y; 
private int screenH; 

public MenuItem(Context ctx, String bmpName, int w, int x, int y, int sX, int sY){ 

    context = ctx; 

    BitmapFactory.Options bmpFOptions = new BitmapFactory.Options(); 
    bmpFOptions.inDensity = 1; 
    bmpFOptions.inScaled = false; 

    int res = context.getResources().getIdentifier(bmpName, "drawable", ctx.getPackageName()); 
    bmp = BitmapFactory.decodeResource(ctx.getResources(), res, bmpFOptions); 

    srcWidth = w; 
    srcHeight = bmp.getHeight(); 

    this.x = x; 
    this.y = y; 

    screenH = sY; 

    sourceRect = new Rect(0,0, srcWidth, srcHeight); 
    destRect = new RectF(); 

    setProportionalDestinationRect(sX, sY); 
} 

private void setProportionalDestinationRect(int scrX, int scrY) { 
    if (scrX != 1024 || scrY != 552){ 
     float propX = (float)scrX/1024; 
     float propY = (float)scrY/600; 
     // All drawables are designed for 1024x600 screen 
     // if device screen is different, scale image proportionally 

     destW = (int)(srcWidth * propX); 
     destH = (int) (srcHeight * propY); 
     x = (int) (x*propX); 
     y = (int) (y*propY); 
    } 
    else { 
     destW = srcWidth; 
     destH = srcHeight; 
    } 
    destRect.set(x,y, x+destW,y+destH); 
} 

public void update(){ 
} 

public Bitmap getBmp() { 
    return bmp; 
} 

public void setBmp(Bitmap bmp) { 
    this.bmp = bmp; 
} 

public Rect getSourceRect() { 
    return sourceRect; 
} 

public void setSourceRect(Rect sourceRect) { 
    this.sourceRect = sourceRect; 
} 

public RectF getDestRect() { 
    return destRect; 
} 

public void setDestRect(RectF destRect) { 
    this.destRect = destRect; 
} 

public boolean contains(int x, int y){ 
    if (destRect.left <= x && destRect.right >= x) 
     if (destRect.top <= y && destRect.bottom >= y) 
      return true; 
    return false; 
} 

public void setY(int y) { 
    this.y = y; 
    if (screenH != 552){ 
     float propY = (float)screenH/600; 
     y = (int) (y*propY); 
    } 
    destRect.set(x,y, x+destW,y+destH); 
} 
} 

MainActivity

,174 51,515,
public class MainActivity extends Activity { 
private boolean backPressedOnce = false; 
long backPressedTime = 0; 

private MainActivitySurface mainActivitySurface; 

globalApp app; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //Setting full screen 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    View decorView = getWindow().getDecorView(); 
    int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 
    decorView.setSystemUiVisibility(uiOptions); 


    int x = getIntent().getIntExtra("screenWidth", 500); 
    int y = getIntent().getIntExtra("screenHeight", 500); 

    app = (globalApp) getApplication(); 
    app.buildSoundPool(); 
    app.loadSounds(); 

    mainActivitySurface = new MainActivitySurface(this, app, x, y); 
    mainActivitySurface.setParentActivity(MainActivity.this); 

    setContentView(mainActivitySurface); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == 1001) { 
     if (resultCode == RESULT_OK) { 
      int result = data.getIntExtra("difficulty", 3); 
      mainActivitySurface.setResultDifficulty(result); 
     } 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    mainActivitySurface.pause(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    backPressedOnce = false; 

    mainActivitySurface.resume(); 
} 

@Override 
public void onBackPressed() { 
     if (backPressedOnce && backPressedTime + 2000 > System.currentTimeMillis()) { 
      Process.killProcess(Process.myPid()); 
      System.exit(1); 
     } else { 
      Toast.makeText(this, "Press back again to exit.", Toast.LENGTH_SHORT).show(); 
      backPressedOnce = true; 
     } 
     backPressedTime = System.currentTimeMillis(); 
} 
} 

MainActivitySurface

public class MainActivitySurface extends SurfaceView implements Runnable { 

private Context context; 
private SurfaceHolder surfaceHolder; 
private Canvas canvas; 

private Thread thread = null; 

volatile private boolean running = false; 
private boolean surfaceCreated = false; 

private Intent playIntent; 
private Intent difficultyIntent; 

// Screen size 
private int screenWidth, screenHeight; 

//Menu items 
private MenuItem menuItemPlay, menuItemDifficulty, middleBarrel, bg; 
private int difficulty = 3; 

private Activity parentActivity; 
private globalApp app; 

public MainActivitySurface(Context ctx, globalApp a, int scrW, int scrH){ 
    super(ctx); 

    context = ctx; 
    screenHeight = scrH; 
    screenWidth = scrW; 

    app = a; 

    surfaceHolder = getHolder(); 

    surfaceHolder.addCallback(new SurfaceHolder.Callback() { 
     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
      surfaceCreated = true; 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 

     } 
    }); 

    bg = new MenuItem(context, "main_activity_background_single", 1024, 0, 0, scrW, scrH); 
    menuItemPlay = new MenuItem(context, "menu_item_play_single", 233,(1024-233)/2,100, scrW, scrH); 
    menuItemDifficulty = new MenuItem(ctx, "menu_item_difficulty_single", 520,(1024 - 520)/2,400,scrW,scrH); 
    middleBarrel = new MenuItem(ctx, "middle_barrel_single", 323,(1024-323)/2,200,scrW,scrH); 

    playIntent = new Intent(context, GameActivity.class); 
    playIntent.putExtra("screenWidth", screenWidth); 
    playIntent.putExtra("screenHeight", screenHeight); 
} 

@Override 
public void run() { 
    while (running){ 
     draw(); 
    } 
} 

private void draw() { 
    if(surfaceHolder.getSurface().isValid()){ 
     canvas = surfaceHolder.lockCanvas(); 

     canvas.drawBitmap(bg.getBmp(), bg.getSourceRect(), bg.getDestRect(), null); 
     canvas.drawBitmap(menuItemPlay.getBmp(), menuItemPlay.getSourceRect(), menuItemPlay.getDestRect(), null); 
     canvas.drawBitmap(menuItemDifficulty.getBmp(), menuItemDifficulty.getSourceRect(), menuItemDifficulty.getDestRect(), null); 
     canvas.drawBitmap(middleBarrel.getBmp(), middleBarrel.getSourceRect(), middleBarrel.getDestRect(), null); 

     surfaceHolder.unlockCanvasAndPost(canvas); 
    } 
} 

public void resume(){ 
    running = true; 
    thread = new Thread(this); 
    thread.start(); 
} 

public void pause(){ 
    running = false; 
    boolean retry = false; 
    while (retry) { 
     try { 
      thread.join(); 
      retry = false; 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
      Log.d("info", "MainActivitySurface: Error joining thread"); 
     } 
    } 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    switch (event.getAction() & event.ACTION_MASK){ 
     case MotionEvent.ACTION_UP: 
      if (menuItemPlay.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       parentActivity.startActivity(playIntent); 
       parentActivity.overridePendingTransition(0,0); 
       break; 
      } 
      if (menuItemDifficulty.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       difficultyIntent = new Intent(parentActivity, DifficultyActivity.class); 
       difficultyIntent.putExtra("screenWidth", screenWidth); 
       difficultyIntent.putExtra("screenHeight", screenHeight); 
       difficultyIntent.putExtra("difficulty", difficulty); 
       parentActivity.startActivityForResult(difficultyIntent, 1001); 
       parentActivity.overridePendingTransition(0, 0); 
       break; 
      } 
    } 
    return true; 
} 

public void setParentActivity(Activity act){ 
    parentActivity = act; 
} 

public void setResultDifficulty(int diff){ 
    difficulty = diff; 
    playIntent.putExtra("difficulty", difficulty); 
} 
} 

DifficultyActivity

public class DifficultyActivity extends Activity { 

private DifficultySurface surface; 
private globalApp app; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //Setting full screen 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    View decorView = getWindow().getDecorView(); 
    int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 
    decorView.setSystemUiVisibility(uiOptions); 

    app = (globalApp) getApplication(); 

    surface = new DifficultySurface(this, app, getIntent().getIntExtra("screenWidth", 500), getIntent().getIntExtra("screenHeight", 500)); 
    setContentView(surface); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    app.soundPool.release(); 
    surface.pause(); 
    overridePendingTransition(0, 0); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    app.buildSoundPool(); 
    app.loadSounds(); 
    surface.resume(); 
} 
} 

DifficultySurface

public class DifficultySurface extends SurfaceView implements Runnable { 

private SurfaceHolder surfaceHolder; 
private Thread thread = null; 
private Canvas canvas; 
private Context context; 
private globalApp app; 

private boolean surfaceCreated = false; 
private boolean running = false; 

private MenuItem bgProp, arrowBarrel, okButton, diffVeryEasy, diffEasy, diffNormal, diffHard, diffVeryHard; 

private int difficulty; 

public DifficultySurface(Context ctx, globalApp a, int scrW, int scrH){ 
    super(ctx); 

    context = ctx; 

    app = a; 

    surfaceHolder = getHolder(); 

    surfaceHolder.addCallback(new SurfaceHolder.Callback() { 
     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
      surfaceCreated = true; 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 

     } 
    }); 

    difficulty = ((Activity)context).getIntent().getIntExtra("difficulty", 3); 

    bgProp = new MenuItem(ctx, "difficulty_background", 1024, 0, 0, scrW, scrH); 

    diffVeryEasy = new MenuItem(ctx, "very_easy",796, 100, 100, scrW, scrH); 
    diffEasy = new MenuItem(ctx, "easy",796, 100, 200 , scrW, scrH); 
    diffNormal = new MenuItem(ctx, "normal",796, 100, 300, scrW, scrH); 
    diffHard = new MenuItem(ctx, "hard",796, 100, 400 , scrW, scrH); 
    diffVeryHard = new MenuItem(ctx, "very_hard",796, 100, 500, scrW, scrH); 
    okButton = new MenuItem(ctx, "ok_button", 100, 924, 500, scrW, scrH); 

    arrowBarrel = new MenuItem(ctx, "barrel_arrow", 100, 0, 100*difficulty, scrW, scrH); 
} 

@Override 
public void run() { 
    while (running) { 
     if (surfaceCreated) { 
      update(); 
      draw(); 
     } 
    } 
} 

private void update() { 
    arrowBarrel.setY(difficulty*100); 
} 

private void draw() { 

    if (surfaceHolder.getSurface().isValid()){ 
     canvas = surfaceHolder.lockCanvas(); 


     canvas.drawBitmap(bgProp.getBmp(), bgProp.getSourceRect(), bgProp.getDestRect(), null); 

     canvas.drawBitmap(arrowBarrel.getBmp(), arrowBarrel.getSourceRect(), arrowBarrel.getDestRect(), null); 

     canvas.drawBitmap(diffVeryEasy.getBmp(), diffVeryEasy.getSourceRect(), diffVeryEasy.getDestRect(), null); 
     canvas.drawBitmap(diffEasy.getBmp(), diffEasy.getSourceRect(), diffEasy.getDestRect(), null); 
     canvas.drawBitmap(diffNormal.getBmp(), diffNormal.getSourceRect(), diffNormal.getDestRect(), null); 
     canvas.drawBitmap(diffHard.getBmp(), diffHard.getSourceRect(), diffHard.getDestRect(), null); 
     canvas.drawBitmap(diffVeryHard.getBmp(), diffVeryHard.getSourceRect(), diffVeryHard.getDestRect(), null); 

     canvas.drawBitmap(okButton.getBmp(), okButton.getSourceRect(), okButton.getDestRect(), null); 

     surfaceHolder.unlockCanvasAndPost(canvas); 
    } 

} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    switch (event.getAction() & event.ACTION_MASK){ 
     case MotionEvent.ACTION_UP:{ 
      if (diffVeryEasy.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       difficulty = 1;    } 
      if (diffEasy.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       difficulty = 2; 
      } 
      if (diffNormal.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       difficulty = 3; 
      } 
      if (diffHard.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       difficulty = 4; 
      } 
      if (diffVeryHard.contains((int) event.getX(), (int) event.getY())){ 
       app.playTap(); 
       difficulty = 5; 
      } 
      if (okButton.contains((int)event.getX(), (int) event.getY())){ 
       app.playTap(); 
       ((Activity)context).getIntent().putExtra("difficulty", difficulty); 
       ((Activity)context).setResult(Activity.RESULT_OK, ((Activity)context).getIntent()); 
       ((Activity)context).finish(); 
       ((Activity)context).overridePendingTransition(0, 0); 
      } 
      break; 
     } 
    } 
    return true; 
} 

public void pause(){ 
    running = false; 
    boolean retry = true; 
    while (retry) { 
     try { 
      thread.join(); 
      retry = false; 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    ((Activity)context).overridePendingTransition(0, 0); 
} 

public void resume(){ 
    running = true; 
    thread = new Thread(this); 
    thread.start(); 
} 
} 
,451,515,

GameActivity

public class GameActivity extends Activity { 

private GameSurface surface; 
private globalApp app; 

private int difficulty; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //Setting full screen 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    View decorView = getWindow().getDecorView(); 
    int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 
    decorView.setSystemUiVisibility(uiOptions); 

    difficulty = getIntent().getIntExtra("difficulty", 3); 

    app = (globalApp) getApplication(); 

    surface = new GameSurface(this, app, getIntent().getIntExtra("screenWidth", 500), getIntent().getIntExtra("screenHeight", 500), difficulty); 

    surface.setParentActivity(this); 

    setContentView(surface); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    app.soundPool.release(); 
    surface.pause(); 
} 

@Override 
protected void onPostResume() { 
    super.onPostResume(); 
    app.buildSoundPool(); 
    app.loadSounds(); 
    surface.resume(); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    surface.stop(); 
} 

@Override 
public void onBackPressed() { 
    super.onBackPressed(); 
    finish(); 
} 
} 

게임 정지 내가 DificultyActivity를 시작할 때 두 (I 하나 MenuItem 개체를 누릅니다하지만 아무 일도 발생하지 않습니다) 발생 또는 내가 GameActivity 시작할 때 (게임을 여전히 MainActivity + MainActivitySurface를 보여줍니다).

Android 모니터는 할당 된 메모리가 40MB 미만이므로 비트 맵이 제 의견으로는 안됩니다. 모든 비트 맵을 재사용하려고했지만 문제가있었습니다 (그 이유는 내가 mdpi drawables만을 사용하기로 선택했기 때문에 처음에는 모든 픽셀 밀도를 사용했지만 중단을 유발하는 경우 리소스를 줄이려고했습니다).

+0

프레임 속도와 관련하여 콘솔에 메시지가 표시됩니까? – VVB

+0

당신은 logcat을 의미합니까? 그렇다면 아니오. 게임이 멈 추면 내가 말한 GC 메시지 만 로그에 표시됩니다. 게임이 정상적으로 작동하는 동안 GC 메시지가 로그에 나타 났으므로 GC를 멈추게하는 것이 유일한 GC인지 의심 스럽습니다. – Dragan

+0

로그 strace 게시 – VVB

답변

0

나는 내 문제를 해결했습니다. 질문을 게시 한 후에 나는 this을 만났다. 우리에게는 같은 문제가 있었던 것 같습니다. 드로잉 속도가 느려졌을 때 (thread.sleep 사용) 더 이상 문제가 없었습니다.

나를 도왔던 사람들에게 감사드립니다.

0

코드를 보지 않고도 문제를 찾기가 어렵습니다. 리소스를 처리하는 방법은 없습니다.

그러나 안드로이드 N은 더 나은 메모리 관리를 요구하며 많은 가비지 수집을 불평하므로 원인 중 하나 일 수 있습니다. 사용하지 않는 비트 맵은 재활용해야합니다. RGB_888보다 절반의 메모리가 필요한 기본 비트 맵 구성으로 RGB_565를 사용하십시오.