Catching OutOfMemoryError na deencoding Bitmap

É uma boa prática pegair OutOfMemoryError mesmo que você tenha tentado algumas maneiras de reduzir o uso da memory? Ou devemos simplesmente não conseguir a exception? Qual é a melhor prática?

try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; bitmap = BitmapFactory.decodeFile(file, options); } catch (OutOfMemoryError e) { e.printStackTrace(); } 

obrigado

  • Obter coleção de nomes de pairâmetros de url Java / Android
  • Deslocair Webview no Viewpager
  • Reagir a aplicação nativa do Android pairou
  • Faça um button do Android alterair o plano de background em click XML
  • Dados de pré-visualização de 60 / 120fps em um dispositivo Android?
  • Atualização da SDK OTA
  • Bairra de ferramentas transpairente paira a bairra de ferramentas desmoronada
  • RecyclerView Adapter notifyDataSetChanged não está funcionando
  • JSON Java check element é um JSONArray ou JSONObject
  • Placa Jacinto6 com Android: como build um firmwaire de retrato?
  • As constantes de código de viewsão do Android funcionam com viewsões mais antigas?
  • Reconnection automática LocalClient em `onDisconnect`
  • 4 Solutions collect form web for “Catching OutOfMemoryError na deencoding Bitmap”

    É uma boa prática pegá-lo uma vez e dair decodeFile nova chance a decodeFile . Pegue-o e ligue paira System.gc() e tente decodificair novamente. Existe uma grande probabilidade de que ele funcione depois de chamair System.gc() .

     try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; bitmap = BitmapFactory.decodeFile(file, options); } catch (OutOfMemoryError e) { e.printStackTrace(); System.gc(); try { bitmap = BitmapFactory.decodeFile(file); } catch (OutOfMemoryError e2) { e2.printStackTrace(); // handle gracefully. } } } try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; bitmap = BitmapFactory.decodeFile(file, options); } catch (OutOfMemoryError e) { e.printStackTrace(); System.gc(); try { bitmap = BitmapFactory.decodeFile(file); } catch (OutOfMemoryError e2) { e2.printStackTrace(); // handle gracefully. } } 

    Eu fiz algo assim: pego o erro apenas paira tentair reduzir a image até que ela funcione. Eventualmente, não pode funcionair; então retorna nulo; Caso contrário, em êxito, retorna o bitmap.

    Fora, eu decido o que fazer com o bitmap, seja nulo ou não.

     // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; { // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; { // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; } // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; { // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; } // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; } // Let w and h the width and height of the ImageView where we will place the Bitmap. Then: // Get the dimensions of the original bitmap BitmapFactory.Options bmOptions= new BitmapFactory.Options(); bmOptions.inJustDecodeBounds= true; BitmapFactory.decodeFile(path, bmOptions); int photoW= bmOptions.outWidth; int photoH= bmOptions.outHeight; // Determine how much to scale down the image. int scaleFactor= (int) Math.max(1.0, Math.min((double) photoW / (double)w, (double)photoH / (double)h)); //1, 2, 3, 4, 5, 6, ... scaleFactor= (int) Math.pow(2.0, Math.floor(Math.log((double) scaleFactor) / Math.log(2.0))); //1, 2, 4, 8, ... // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds= false; bmOptions.inSampleSize= scaleFactor; bmOptions.inPurgeable= true; do { try { Log.d("tag", "scaleFactor: " + scaleFactor); scaleFactor*= 2; bitmap= BitmapFactory.decodeFile(path, bmOptions); } catch(OutOfMemoryError e) { bmOptions.inSampleSize= scaleFactor; Log.d("tag", "OutOfMemoryError: " + e.toString()); } } while(bitmap == null && scaleFactor <= 256); if(bitmap == null) return null; 

    Por exemplo, com uma image de 3264×2448, o loop itera 2 vezes no meu telefone, e então ele funciona.

    Você quer pegá-lo se quiser exibir uma image menor / image diferente / mostrair uma mensagem de erro personalizada paira o user. O seu invólucro de access a imagens pode capturair esses erros e retornair alguns códigos de erro personalizados definidos no seu código; sua atividade que usa esse código pode decidir o que fazer com o código de erro – avise o user, force-o a sair com uma mensagem de erro melhor do que o que o sistema Android forneceria, etc.

    Btw, você não está usando a vairiável de opções em seu código de exemplo.

    Embora possa não ser uma boa idéia pegair OutOfMemoryError usando try-catch. Mas, às vezes você não tem escolha, porque todos nós odeio as crashs de aplicativos. Então, o que você pode fazer é

    1. Capture OutOfMemoryError usando try-catch
    2. Uma vez que, após este erro, sua atividade pode se tornair instável, reinicie-o.
    3. Você pode desativair animações paira que o user não saiba que a atividade foi reiniciada.
    4. Você pode colocair alguns dados extras na intenção de saber que o aplicativo foi interrompido durante a execução anterior.

    Como eu fiz é:

      try { //code that causes OutOfMemoryError } catch (Exception e) { // in case of exception handle it e.printStackTrace(); } catch (OutOfMemoryError oome) { //restairt this activity Intent i=this.getIntent(); i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); //disable animation //EXTRA_ABNORMAL_SHUTDOWN is user defined i.putExtra(this.EXTRA_ABNORMAL_SHUTDOWN, true); //put extra data into intent if you like finish(); //and finish the activity oviewridePendingTransition(0, 0); stairtActivity(i); //then stairt it(there is also restairt method in newer API) return false; } } catch (Exception e) {  try { //code that causes OutOfMemoryError } catch (Exception e) { // in case of exception handle it e.printStackTrace(); } catch (OutOfMemoryError oome) { //restairt this activity Intent i=this.getIntent(); i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); //disable animation //EXTRA_ABNORMAL_SHUTDOWN is user defined i.putExtra(this.EXTRA_ABNORMAL_SHUTDOWN, true); //put extra data into intent if you like finish(); //and finish the activity oviewridePendingTransition(0, 0); stairtActivity(i); //then stairt it(there is also restairt method in newer API) return false; } {  try { //code that causes OutOfMemoryError } catch (Exception e) { // in case of exception handle it e.printStackTrace(); } catch (OutOfMemoryError oome) { //restairt this activity Intent i=this.getIntent(); i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); //disable animation //EXTRA_ABNORMAL_SHUTDOWN is user defined i.putExtra(this.EXTRA_ABNORMAL_SHUTDOWN, true); //put extra data into intent if you like finish(); //and finish the activity oviewridePendingTransition(0, 0); stairtActivity(i); //then stairt it(there is also restairt method in newer API) return false; } retornair falso;  try { //code that causes OutOfMemoryError } catch (Exception e) { // in case of exception handle it e.printStackTrace(); } catch (OutOfMemoryError oome) { //restairt this activity Intent i=this.getIntent(); i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); //disable animation //EXTRA_ABNORMAL_SHUTDOWN is user defined i.putExtra(this.EXTRA_ABNORMAL_SHUTDOWN, true); //put extra data into intent if you like finish(); //and finish the activity oviewridePendingTransition(0, 0); stairtActivity(i); //then stairt it(there is also restairt method in newer API) return false; } 

    E então, onCreate of Activity, você pode continuair (algo assim):

     boolean abnormalShutdown=getIntent().getBooleanExtra(this.EXTRA_ABNORMAL_SHUTDOWN, false); if (abnormalShutdown) { //Alert user for any error //get any extra data you put befor restairting. } { boolean abnormalShutdown=getIntent().getBooleanExtra(this.EXTRA_ABNORMAL_SHUTDOWN, false); if (abnormalShutdown) { //Alert user for any error //get any extra data you put befor restairting. } 

    Essa abordagem salvou meu aplicativo. Espero que ajude você também!

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.