我正在使用图片设置为我所有活动的背景,但它导致内存溢出问题并导致应用崩溃。现在我在我的活动中解除暂停()和Destroy()上的drawables,现在按下后退按钮显示空白屏幕。那么如何在不使用额外内存的情况下避免这种情况。
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();
}
最初我使用android:background =“@ drawable /”来扩充我的布局,这总是导致内存溢出错误,说VM不会让我们分配10MB(应用程序)现在我从那个drawable得到一个位图而没有缩放down并在运行时绑定它。现在它说VM不会让我们分配5MB(app。)而不使用unbindDrawables(..) 显然,显示的背景图像的质量有所下降,但我无法理解如果我使用13KB的png文件,JVM如何处理请求需要5或10MB的空间?
我已将布局语句从onCreate()转移到onResume()方法,但应用程序在按下后退按钮时再次耗尽内存。
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();
}
}
答案 0 :(得分:1)
我找到了解决这个问题的方法。现在我将运行时的位图缩放到非常小的尺寸,然后将它们存储在内部存储中。程序在运行时从存储中调用缩放的位图,如果它不存在,则从drawable文件夹中调用它,缩放它,将其写入存储,然后将其绑定到视图。 通过这种方式,无需在任何时间调用unbindDrawables方法,并且应用程序始终保持响应。 我现在唯一关心的是位图的质量,我认为我需要使用缩放尺寸来找出最小尺寸和最高质量的尺寸。
答案 1 :(得分:0)
您正在为每个子视图调用GC。完成所有解除绑定后,尝试只调用一次。
unbindDrawables(findViewById(R.id.login_root));
System.gc();
GC是一个沉重的负载,过于频繁地调用它是没用的。事实上,如果没有泄漏,它应该是必要的。
另外请记住,png文件大小与内存中的位图无关。这里有更多信息 http://developer.android.com/training/displaying-bitmaps/index.html