Изображение с высоким разрешением – OutOfMemoryError

Я разрабатываю приложение для Galaxy S4. Одним из требований приложения является наличие SplashScreen, содержащего изображение 1920×1080 пикселей. Его изображение высокого качества .jpeg и размер изображения составляет около 2 мегабайт .

Проблема в том, что я получаю OutOfMemoryError, как только я запускаю приложение. Я очень ошеломлен, что это уже происходит с размером всего в 2 мегабайта? Как я могу исправить эту проблему и отобразить изображение?

Изменение размеров или размера изображения не является вариантом.

SplashScreen.java

public class Splashscreen extends Activity { private static final int SPLASH_DURATION = 2000; private boolean isBackPressed = false; @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(LayoutParams.FLAG_FULLSCREEN, LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); setContentView(R.layout.splashscreen); Handler h = new Handler(); h.postDelayed(new Runnable() { @Override 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.startActivity(i); overridePendingTransition(R.anim.short_fade_in, R.anim.short_fade_out); } finish(); } }, SPLASH_DURATION); } @Override public void onBackPressed() { isBackPressed = true; super.onBackPressed(); } } 

И splashscreen.xml

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

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:

Иногда (когда доступно много памяти устройства) приложение может пройти мимо экрана заставки, но тогда потребление памяти приложения просто безумие . (Около 100 мегабайт) . Несмотря на то, что я закрываю активность SplashScreen и завершаю (), кажется, что есть ссылка на ImageView / Image, хранящуюся в памяти.

Как уменьшить объем памяти?

Когда я не показываю заставку, мое приложение потребляет всего около 35 МБ памяти. С изображением SplashScreen – около 100 МБ.

Solutions Collecting From Web of "Изображение с высоким разрешением – OutOfMemoryError"

Три подсказки, которые помогут вам:

  1. Используйте это для загрузки изображений, начиная с загрузки больших битмапов Документация для 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 guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } 
  2. Убедитесь, что у вас есть только один экземпляр вашего Bitmap в памяти. После его отображения вызовите recycle() и установите ссылку на null . Вы можете использовать Memory Allocation Tracker, чтобы узнать, что выделено. Вы также можете прочитать файлы HPROF, как это предлагается в комментариях.

  3. По умолчанию ARGB_8888 формат пикселя ARGB_8888 , что означает 4 байта на пиксель. Очень хорошая статья: качество растрового изображения, обвязка и сглаживание . Ваше изображение JPEG, поэтому у него нет прозрачности, поэтому вы тратите 1 байт на каждый пиксель для альфа-канала. Это не очень вероятно, но, возможно, с приемлемым качеством вы можете использовать еще более экономичный формат. Взгляните на них. Может быть, RGB_565 например. Он занимает 2 байта для пикселя, поэтому ваше изображение будет на 50% легче. Вы можете включить сглаживание для улучшения качества RGB_565 .

У меня была аналогичная проблема, и решение прост. Поместите изображение с высоким разрешением 1920×1080 пикселей в каталог drawable-nodpi . Система не масштабирует ресурсы, помеченные этим квалификатором, независимо от плотности текущего экрана, что приводит к OutOfMemoryError, поэтому проблема должна исчезнуть.

Пожалуйста, проверьте документацию на Android: http://developer.android.com/intl/es/guide/practices/screens_support.html

Надеюсь, поможет.