Mistake:

java.lang.OutOfMemoryError имя пакета.MainActivity.onCreate 

Markup:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:keepScreenOn="true" android:background="@drawable/button_task"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/line1"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/text_0" android:textSize="24sp" android:paddingEnd="10dp" android:paddingStart="10dp" android:text="@string/good_text_0" android:visibility="gone" android:layout_weight="4" android:gravity="center" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/text_1" android:textSize="24sp" android:paddingEnd="10dp" android:paddingStart="10dp" android:gravity="center" android:layout_weight="4" android:text="@string/good_text_1" android:visibility="gone" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/text_2" android:textSize="24sp" android:paddingEnd="10dp" android:paddingStart="10dp" android:gravity="center" android:layout_weight="4" android:text="@string/good_text_2" android:visibility="gone" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/text_3" android:textSize="24sp" android:paddingEnd="10dp" android:paddingStart="10dp" android:gravity="center" android:layout_weight="4" android:text="@string/good_text_3" android:visibility="gone" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/text_4" android:textSize="24sp" android:paddingEnd="10dp" android:paddingStart="10dp" android:gravity="center" android:layout_weight="4" android:text="@string/good_text_4" android:visibility="gone" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/text_5" android:textSize="24sp" android:paddingEnd="10dp" android:paddingStart="10dp" android:gravity="center" android:layout_weight="4" android:text="@string/good_text_5" android:visibility="gone" android:textColor="@color/colorAccent" /> </LinearLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/frame2" android:visibility="gone"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/image1" android:scaleType="centerCrop" android:visibility="gone" /> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/image2" android:scaleType="centerCrop" android:visibility="gone" /> </FrameLayout> 

Code:

 import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.TimeUnit; public class MainActivity extends AppCompatActivity { SharedPreferences sPref; SharedPreferences.Editor ed; DB db; TextView text_0, text_1, text_2, text_3, text_4, text_5; ImageView image1, image2; LinearLayout line1; FrameLayout frame2; Animation anim, anim_im_1, anim_im_0; int stringID, j; String package_name; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // полноэкранный "липкий" режим lipkiy(); // воспроизведение песни // создаем плеер и указываем ему нужный файл для проигрывания MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.serdtse); // создаем менеджер управления громкостью звука AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); // устанавливаем громкость звука audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (maxVolume * 9) / 10, 0); // воспроизвести только 1 раз mp.setLooping(false); mp.start(); //При завершении воспроизводства очистить приогрыватель mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { mp.release(); } }); //получаем данные из файла "Pref" sPref = getSharedPreferences("Pref", MODE_PRIVATE); ed = sPref.edit(); // открываем подключение к БД db = new DB(this); db.open(); nachalo(); } // приветствие и начало работы protected void nachalo() { text_0 = (TextView) findViewById(R.id.text_0); text_1 = (TextView) findViewById(R.id.text_1); text_2 = (TextView) findViewById(R.id.text_2); text_3 = (TextView) findViewById(R.id.text_3); text_4 = (TextView) findViewById(R.id.text_4); text_5 = (TextView) findViewById(R.id.text_5); package_name = getApplicationContext() . getPackageName(); image1 = (ImageView) findViewById(R.id.image1); image2 = (ImageView) findViewById(R.id.image2); line1 = (LinearLayout) findViewById(R.id.line1); frame2 = (FrameLayout) findViewById(R.id.frame2); // создаем объект анимации из файла anim/myalpha anim = AnimationUtils.loadAnimation(this, R.anim.myalpha); anim_im_1 = AnimationUtils.loadAnimation(this, R.anim.alpha_image_1); anim_im_0 = AnimationUtils.loadAnimation(this, R.anim.alpha_image_0); Thread t = new Thread(new Runnable() { public void run() { try { TimeUnit.SECONDS.sleep(1); for ( int i = 0; i < 6; i++) { ed . putInt("i", i); ed . commit(); runOnUiThread(runn0); //появление с анимацией TimeUnit.MILLISECONDS.sleep(4000); // пауза для показа надписи runOnUiThread(runn0_1); //исчезновение TimeUnit.MILLISECONDS.sleep(1950); // пауза для анимации runOnUiThread(runn0_2); //невидимая надпись TimeUnit.SECONDS.sleep(2); // пауза пустой экран } runOnUiThread(run_frame); // видимый новый фрейм for ( int i = 0; i < 17; i++) { ed . putInt("i", i); ed . commit(); runOnUiThread(run_image); TimeUnit.MILLISECONDS.sleep(1950); //runOnUiThread(run_image_2); TimeUnit.MILLISECONDS.sleep(8800); } runOnUiThread(runn6); } catch (InterruptedException e) {e.printStackTrace();} } }); t.start(); } Runnable run_frame = new Runnable() { public void run() { // делаем видимым слайды frame2 . setVisibility(View.VISIBLE); line1 . setVisibility(View.GONE); } }; Runnable run_image = new Runnable() { public void run() { // запускаем анимацию switch (sPref.getInt("i", 0)) // в зависимости от номера { case 0: //первый слайд image1 . setImageResource(R.drawable.k_0); image1 . setVisibility(View.VISIBLE); image1 . startAnimation(anim_im_1); break; case 1: // второй слайд image2 . setImageResource(R.drawable.k_1); image2 . setVisibility(View.VISIBLE); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 2: // слайд 3 image1 . setImageResource(R.drawable.k_2); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 3: // слайд 4 image2 . setImageResource(R.drawable.k_3); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 4: // версия два image1 . setImageResource(R.drawable.k_4); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 5: // версия два image2 . setImageResource(R.drawable.k_5); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 6: // версия два image1 . setImageResource(R.drawable.k_6); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 7: // версия два image2 . setImageResource(R.drawable.k_7); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 8: // версия два image1 . setImageResource(R.drawable.k_8); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 9: // версия два image2 . setImageResource(R.drawable.k_9); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 10: // версия два image1 . setImageResource(R.drawable.k_10); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 11: // версия два image2 . setImageResource(R.drawable.k_11); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 12: // версия два image1 . setImageResource(R.drawable.k_12); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 13: // версия два image2 . setImageResource(R.drawable.k_13); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 14: // версия два image1 . setImageResource(R.drawable.k_14); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; case 15: // версия два image2 . setImageResource(R.drawable.k_15); image2 . startAnimation(anim_im_1); image1 . startAnimation(anim_im_0); break; case 16: // версия два image1 . setImageResource(R.drawable.k_16); image1 . startAnimation(anim_im_1); image2 . startAnimation(anim_im_0); break; } } }; Runnable runn0 = new Runnable() { public void run() { // запускаем анимацию switch (sPref.getInt("i", 0)) // в зависимости от номера { case 0: //первый запуск text_0 . startAnimation(anim); text_0 . setVisibility(View.VISIBLE); break; case 1: // версия один text_1 . startAnimation(anim); text_1 . setVisibility(View.VISIBLE); break; case 2: // версия два text_2 . startAnimation(anim); text_2 . setVisibility(View.VISIBLE); break; case 3: // версия два text_3 . startAnimation(anim); text_3 . setVisibility(View.VISIBLE); break; case 4: // версия два text_4 . startAnimation(anim); text_4 . setVisibility(View.VISIBLE); break; case 5: // версия два text_5 . startAnimation(anim); text_5 . setVisibility(View.VISIBLE); break; } } }; Runnable runn0_1 = new Runnable() { public void run() { // запускаем анимацию switch (sPref.getInt("i", 0)) // в зависимости от номера { case 0: //первый запуск text_0 . startAnimation(anim_im_0); break; case 1: // версия один text_1 . startAnimation(anim_im_0); break; case 2: // версия два text_2 . startAnimation(anim_im_0); break; case 3: // версия два text_3 . startAnimation(anim_im_0); break; case 4: // версия два text_4 . startAnimation(anim_im_0); break; case 5: // версия два text_5 . startAnimation(anim_im_0); break; } } }; Runnable runn0_2 = new Runnable() { public void run() { // запускаем анимацию switch (sPref.getInt("i", 0)) // в зависимости от номера { case 0: //первый запуск text_0 . setVisibility(View.GONE); break; case 1: // версия один text_1 . setVisibility(View.GONE); break; case 2: // версия два text_2 . setVisibility(View.GONE); break; case 3: // версия два text_3 . setVisibility(View.GONE); break; case 4: // версия два text_4 . setVisibility(View.GONE); break; case 5: // версия два text_5 . setVisibility(View.GONE); break; } } }; Runnable runn6 = new Runnable() { public void run() { startActivity(new Intent(MainActivity.this, FAQ.class)); MainActivity.this.finish(); overridePendingTransition(R.anim.alpha_to_1, R.anim.alpha_to_0); } }; protected void onDestroy() { super.onDestroy(); // закрываем подключение при выходе db.close(); } // полноэкранный "липкий" режим protected void onStart() { super.onStart(); lipkiy(); } // полноэкранный "липкий" режим protected void lipkiy () { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } } 

I would appreciate specific suggestions with code examples.

  • Tell me, why are there so many imageViews in your markup? I'm afraid the problem is that you have too many images. Reconsider the logic; you can use RecyclerView or make images as small as possible. - Vitaly Tomashevsky
  • You do not need 17 ImageView , since only two can be visible at a time. The meaning is this: when the slide has worked and is already hidden, we change the picture in it, cancel what the animation has done and reuse it for the next slide. - woesss
  • @woesss, initially, I, too, according to your logic, created only 2 imageViews and alternately loaded images there. However, I encountered an unexpected difficulty: I could not achieve dynamic image loading with stringID = getResources (). GetIdentifier ("k_" + j, "drawable", package_name); and then assigning it to an ImageView inside Runnable run_image = new Runnable (). Each image size is 28 - 46 KB. RecyclerView - still with 5.0, and the error occurs just for users with android 4.2 - 4.4. - St-st
  • Why these perversions? id resources are known in advance and in the same swith you know what resource is needed. And if you want to refer to them by their ordinal number, you can put them in an array and take by index: private int[] ids = { R.drawable.k_0, R.drawable.k_1, ...}; ... imageView.setImageResource(ids[j]); - woesss
  • @woesss, I misled you by explaining why I created 17 ImageView. Only now, when I returned to two and got the same effect, I remembered the reason: with two ImageView, the playback of the mp3 file is interrupted. I connected this with the fact that ImageView is assigned a drawing from resources and this procedure stops playback. Tell me something in this regard? PS and the initial perversions were associated with the desire to sort out the names of resources in a cycle, not hands. Now, when all 17 cases are painted, you are absolutely right, and you can register with your hands. New code will fix in the question. - St-st

1 answer 1

There are three solutions to your problem. For greater efficiency, it is better to use all three:

The first. As suggested by @Vitaly Tomashevsky in the comments above - redraw the markup and add RecyclerView to it, instead of the ImageView heap.

Second. Optimize the images themselves by compressing them through any such service. For example such .

The third, the most effective. Take advantage of the Picasso library. To do this in Gradle write:

 dependencies { ... compile 'com.squareup.picasso:picasso:2.5.2' } 

In the code where necessary:

Picasso.with(активность).load(R.drawable.ваш_img).into(R.id.ваш_ImageView);

and add pictures dynamically.

Usually, all three components remove my problems with OOM :)

  • I would replace Picasso with Glide - all other things being equal, Glide consumes less resources and works faster, but weighs more than Picasso. - Evgen Orlovsky
  • Compressing files through these services will not help here. This can only reduce the size of apk, but can not cope with OOM. Since ImageView stores Bitmap in memory, the size of the image (width and height) and the bitmap mode affect the size of the occupied memory. And how it is presented as a file anyway. Although there is png at least jpeg, at least with losses even without loss. - eugeneek
  • The size of each image within 28 - 46 KB. RecyclerView - still with 5.0, and the error occurs just for users with android 4.2 - 4.4. I was inclined to think that I was wrong with images. dokupash advises using ImageView imgView = (ImageView) page.findViewById (R.id.img); imgView.setImageResource (R.drawable.at1); delate (imgView) in response to ru.stackoverflow.com/questions/241281/… , but I don’t understand how its offer works and works. - St-st
  • @Evgen Orlovsky. Can you explain what Picasso and Glide do? Do I need to additionally download the Picasso and Glide libraries, or is it enough to add 2 lines that are indicated in the answer? - St-st
  • The @ st-st in the answer in the first line is the connection of the library in Gradle, the second line is the use of the library to load the image. Picasso and Glide simply optimize the work with images, and they are very similar in use - but there are cardinal differences in the mechanisms, I personally think that Glide is a file of Picasso. If you use a lot of images in the project, you definitely need to use third-party libraries and not to fence your processing, and you will save time and optimization will be several times higher. - Evgen Orlovsky