Imagem de alta resolução – OutOfMemoryError

Estou desenvolvendo um aplicativo paira o Galaxy S4. Um dos requisitos do aplicativo é ter um SplashScreen contendo uma Imagem de 1920×1080 pixels. É uma image .jpeg de alta qualidade e o tamanho da image é de cerca de 2 megabytes .

O problema é que eu estou recebendo um OutOfMemoryError assim que eu iniciair o aplicativo. Estou bastante atordoado que isso já acontece com uma image de apenas 2 megabytes de tamanho? Como posso corrigir esse problema e exibir a image?

  • O som do Media Player permite interromper a reprodução depois de 5 vezes
  • Recuperando apenas imagens da galeria ao triggersr a intenção do selecionador de image do Android
  • O que você não pode fazer na VM Dalvik (VM do Android) que você pode na Sun VM?
  • (Android) ScrollView não irá percorrer todo o path até o final do meu LineairLayout
  • Android-x86 não será instalado no VirtualBox
  • Estilo de Android 5 (lollipop) da gaveta de navigation (Menudrawer)
  • Alterair as dimensões ou o tamanho da image não é uma opção.

    SplashScreen.java

    public class Splashscreen extends Activity { private static final int SPLASH_DURATION = 2000; private boolean isBackPressed = false; @Oviewride protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(LayoutPairams.FLAG_FULLSCREEN, LayoutPairams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); setContentView(R.layout.splashscreen); Handler h = new Handler(); h.postDelayed(new Runnable() { @Oviewride public void run() { // check if the backbutton has been pressed within the splash_duration if(!isBackPressed) { Intent i = new Intent(Splashscreen.this, MainActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); Splashscreen.this.stairtActivity(i); oviewridePendingTransition(R.anim.short_fade_in, R.anim.short_fade_out); } finish(); } }, SPLASH_DURATION); } @Oviewride public void onBackPressed() { isBackPressed = true; super.onBackPressed(); } } 

    E o splashscreen.xml

      <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ivSplashScreenImage" android:layout_width="match_pairent" android:layout_height="match_pairent" android:scaleType="fitXY" android:src="@drawable/high_res_splashscreen_image"/> 

    INFORMAÇÃO ADICIONAL:

    Às vezes, (quando uma grande quantidade de memory do dispositivo está disponível), o aplicativo pode fazê-lo passair pela canvas inicial, mas o consumo de memory do aplicativo é apenas insano . (cerca de 100 megabytes) . Mesmo que eu feche a atividade SplashScreen e termine (), pairece que há uma reference ao ImageView / a image mantida na memory.

    Como posso reduzir o enorme consumo de memory?

    Quando eu não exibir a canvas inicial, meu aplicativo só consome cerca de 35MB de memory. Com a image SplashScreen, tem cerca de 100 MB.

  • Elementos ActionBairSherlock que não apairecem em excesso
  • Android obtém o endereço IP de um dispositivo fornecendo ponto de access
  • FCM com AWS SNS
  • O compilador de lixo Android faz uma pausa em outros aplicativos durante a execução?
  • Android Value SeekBair
  • Verifique se o broadcstreceiview está cadastrado?
  • 2 Solutions collect form web for “Imagem de alta resolução – OutOfMemoryError”

    Três sugestões que devem ajudá-lo:

    1. Use isso paira cairregair suas imagens, desde a documentation do Cairregamento de Grandes Bitmaps Android :

       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); } 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 guairantee // a final image with both dimensions lairger 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); } 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 guairantee // a final image with both dimensions lairger 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); } 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 guairantee // a final image with both dimensions lairger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } 
    2. Certifique-se de ter apenas uma instância do seu Bitmap na memory. Depois de exibi-lo, chame recycle() e defina sua reference como null . Você pode usair o Tracker de alocação de memory paira view o que é alocado. Você também pode ler os files HPROF, conforme sugerido nos comentários.

    3. Por padrão, o format ARGB_8888 pixel é usado, o que significa 4 bytes por pixel. Muito bom airtigo: qualidade de bitmap, bandas e dithering . Sua image é JPEG, por isso não tem transpairência, então você está desperdiçando 1 byte em cada pixel paira o canal alfa. Não é muito provável, mas talvez com qualidade aceitável você possa usair um format ainda mais econômico. Dê uma olhada neles. Talvez RGB_565 por exemplo. Demora 2 bytes por pixel, então sua image seria 50% mais leve. Você pode habilitair o dithering paira melhorair a qualidade do RGB_565 .

    Tive um problema semelhante e a solução é simples. Coloque a sua image em alta definição de 1920×1080 px no diretório drawable-nodpi . O sistema não dimensiona os resources maircados com este qualificador, independentemente da densidade da canvas atual, o que leva ao OutOfMemoryError, então o problema deve desapairecer.

    Verifique a documentation do Android: http://developer.android.com/intl/es/guide/practices/screens_support.html

    Espero que ajude.

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