Unbinding drawables onPause (), causing unresponsive reverse navigation and skipping this step, causes a memory overflow

I use the image to set as the background for all my activities, but this causes a memory overflow problem and causes the application to crash. Now I turn off my drawables on pause () and Destroy () in my activity, and now it shows a blank screen when I press the return button. So how can I avoid this without using extra memory.

protected void onPause(){ super.onPause(); unbindDrawables(findViewById(R.id.login_root)); } protected void onDestroy() { unbindDrawables(findViewById(R.id.login_root)); super.onDestroy(); } private void unbindDrawables(View view) { System.gc(); Runtime.getRuntime().gc(); if (view.getBackground() != null) { view.getBackground().setCallback(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } ((ViewGroup) view).removeAllViews(); } 

Initially, I inflated my layout using the android: background = "@ drawable /", which always caused a memory overflow error, saying that the VM does not allow us to allocate 10 MB (application). Now I get the bitmap from this drawing without scaling down and bind it to runtime.Now he says that VM will not allow us to allocate 5 MB (application) without using unbindDrawables (..) Obviously, the quality of the background image that is shown has decreased , but I can’t understand that if I use a 13 KB png file, how does the JVM require 5 or 10 MB of space to process the request?

I transfer my build instructions from the onCreate () method to the onResume () method, but when I click the application again, it presses the back button.

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } protected void onResume(){ setContentView(R.layout.home); Bitmap bmp; ImageView background = (ImageView)findViewById(R.id.iv_home_background); InputStream is = getResources().openRawResource(R.drawable.background); bmp = BitmapFactory.decodeStream(is); background.setImageBitmap(bmp); super.onResume(); } protected void onPause(){ super.onPause(); unbindDrawables(findViewById(R.id.home_root)); } private void unbindDrawables(View view) { System.gc(); Runtime.getRuntime().gc(); if (view.getBackground() != null) { view.getBackground().setCallback(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } ((ViewGroup) view).removeAllViews(); } } 
+6
source share
2 answers

I found a job for this problem. Now I scale my bitmap images at runtime to a very small size, and then save them to internal storage. The program calls scaled bitmaps from the repository at runtime, and if it is not there, it calls it from the drop-down folder, scales it, writes it to the repository, and then binds it to the view. Thus, there is no need to call the unbindDrawables method at any time, and the application remains flexible in everything. My only problem right now is the quality of the bitmaps, I think I need to play around with the zoom size to find out the smallest possible size with the highest quality.

+1
source

You invoke GC for each additional view. Try calling him only once when everyone is unfolding.

 unbindDrawables(findViewById(R.id.login_root)); System.gc(); 

GC is a heavy load and it is useless to call it too often. in fact, if there are no leaks, it should generally be unsightly.

Also keep in mind that the size of the png file has nothing to do with the bitmap in memory. Here is more detailed information about this http://developer.android.com/training/displaying-bitmaps/index.html

0
source

Source: https://habr.com/ru/post/925246/


All Articles