简体   繁体   English

清除Android 2.3.3中活动的所有位图的有效方法

[英]Efficient way to clean all bitmaps of an activity in Android 2.3.3

I'm currently working on an embedded device using Android 2.3.3 with very few memory. 我目前正在使用内存很少的使用Android 2.3.3的嵌入式设备。 The GUI is using lot of bitmaps, and sometimes, we saw some OutOfMemory exceptions due to Android not handling the bitmap memory well enough to free the memory fast enough for a new activity to start correctly. GUI使用了很多位图,有时,我们会看到一些OutOfMemory异常,这是因为Android对位图内存的处理不够好,无法足够快地释放内存,因此新活动无法正确启动。

To be exact, Android official documentation ( https://developer.android.com/training/displaying-bitmaps/manage-memory.html ) tells us : 确切地说,Android官方文档( https://developer.android.com/training/displaying-bitmaps/manage-memory.html )告诉我们:

On Android 2.3.3 (API level 10) and lower, the backing pixel data for a bitmap is stored in native memory. 在Android 2.3.3(API级别10)及更低版本上,位图的支持像素数据存储在本机内存中。 It is separate from the bitmap itself, which is stored in the Dalvik heap. 它与位图本身是分开的,位图本身存储在Dalvik堆中。 The pixel data in native memory is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash. 本机内存中的像素数据无法以可预测的方式释放,可能导致应用程序短暂超过其内存限制并崩溃。

In Android 2.3.3 (API level 10) and lower, using recycle() is recommended. 在Android 2.3.3(API级别10)及更低版本中,建议使用recycle()。 If you're displaying large amounts of bitmap data in your app, you're likely to run into OutOfMemoryError errors. 如果您在应用程序中显示大量位图数据,则很可能会遇到OutOfMemoryError错误。 The recycle() method allows an app to reclaim memory as soon as possible. recycle()方法允许应用程序尽快回收内存。

Caution: You should use recycle() only when you are sure that the bitmap is no longer being used. 警告:只有在确定不再使用位图时,才应使用recycle()。 If you call recycle() and later attempt to draw the bitmap, you will get the error: "Canvas: trying to use a recycled bitmap". 如果调用recycle()并稍后尝试绘制位图,则会收到错误:“画布:尝试使用回收的位图”。

So I started to implement some recycle() in onDestroy() but I'm facing different issues : 所以我开始在onDestroy()中实现一些recycle(),但是我面临着不同的问题:

-onDestroy() is not reliable, since we can't be sure Android will call it before fully kill the application. -onDestroy()不可靠,因为我们无法确定Android在完全终止应用程序之前会调用它。 So, even if it seems to be the good place to clean bitmaps, it may happen that an activity is instantly killed while another starts and can't allocated memory for its own bitmaps. 因此,即使它似乎是清理位图的好地方,也可能发生这样的情况,即一个活动被立即杀死,而另一个活动开始,并且无法为其自己的位图分配内存。

  • Would there be a better place to implement the recycling of bitmaps? 会有更好的地方实现位图的回收吗?

-Some drawables are declared through Java code, those are easy to recycle since we can keep a reference to them. -一些可绘制对象通过Java代码声明,这些易于回收,因为我们可以保留对它们的引用。 But what about the ones declared through Xml? 但是通过Xml声明的那些呢?

  • Is there a way to find all BitmapDrawable of a view (without looking the full view tree)? 有没有一种方法可以找到视图的所有BitmapDrawable(不查找整个视图树)?
  • How Android is managing XML-declared drawable? Android如何管理XML声明的可绘制对象? Is there only one java object / xml object? 是否只有一个Java对象/ xml对象? (meaning you could have some issues if a xml reference is used in several views/activities) Having only one instance of each object would greatly reduce the memory used but would requires much more logic to be clean properly. (这意味着如果在多个视图/活动中使用xml引用,您可能会遇到一些问题。)每个对象只有一个实例将大大减少所使用的内存,但需要更多逻辑才能正确清理。

Those specific questions lead to the main issue : How to handle bitmaps to be sure that before another onCreate(), we cleaned every bitmap of the previous activity? 这些特定的问题导致了主要问题:如何处理位图,以确保在另一个onCreate()之前,我们清除了先前活动的每个位图?

Thanks! 谢谢!

you can use finalize() method for perform certain tasks. 您可以使用finalize()方法执行某些任务。
This way,you can double check that memory is released. 这样,您可以再次检查是否释放了内存。

Finalize() Finalize()
finalize() method is a protected and non-static method of java.lang.Object class. finalize()方法是java.lang.Object类的一种受保护的非静态方法。 This method will be available in all objects you create in java. 在Java中创建的所有对象中都可以使用此方法。 This method is used to perform some final operations or clean up operations on an object before it is removed from the memory. 此方法用于在将对象从内存中删除之前对对象执行某些最终操作或清理操作。 you can override the finalize() method to keep those operations you want to perform before an object is destroyed. 您可以覆盖finalize()方法以保留要在销毁对象之前执行的那些操作。 Here is the general form of finalize() method. 这是finalize()方法的一般形式。

example

        @Override
         protected void finalize() throws Throwable
         {
              System.out.println("From Finalize Method");
          }

Another way 其他方式
Another way of implementation is by downsampling and caching of bitmaps. 另一种实现方式是对位图进行下采样缓存 If caching is efficient,then you can assisn and release bitmaps on onstart() and onStop() methods.So you can release memory as soon as the activity is out of focus. 如果缓存效率很高,那么您可以在onstart()和onStop()方法上辅助和释放位图。因此,只要活动没有重点,就可以释放内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM