jot*_*tos 151 android memory-leaks
我已经开发了一个Android应用程序,我正处于手机应用程序开发阶段,其中一切似乎都运行良好,你想宣布胜利和发货,但你知道只需要一些内存和资源泄漏在那里; Android上只有16mb的堆,而且在Android应用程序中显然很容易泄漏.
我一直在环顾四周,到目前为止只能找到关于'hprof'和'traceview'的信息并且没有得到很多好评.
您在OS项目中遇到或开发并关心分享哪些工具或方法?
hp.*_*oid 90
我发现开发Android应用程序的最常见错误之一是"java.lang.OutOfMemoryError:Bitmap Size Exceeds VM Budget"错误.我在更改方向后使用大量位图的活动中发现了这个错误:活动被销毁,再次创建,布局从消耗可用于位图的VM内存的XML中"膨胀".
前一个活动布局上的位图未被垃圾收集器正确释放,因为它们已经交叉引用了它们的活动.经过多次实验,我发现了一个很好的解决方案.
首先,在XML布局的父视图上设置"id"属性:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/RootView"
>
...
Run Code Online (Sandbox Code Playgroud)
然后,在Activity的onDestroy()方法上,调用unbindDrawables()方法将refence传递给父View,然后执行System.gc()
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
private void unbindDrawables(View view) {
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这个unbindDrawables()方法以递归方式探索视图树,并且:
Tim*_*Ohr 28
主要针对未来的Google旅行者:
遗憾的是,大多数java工具都不适合这项任务,因为它们只分析JVM-Heap.但是,每个Android应用程序也都有一个本机堆,它也必须符合~16 MB的限制.例如,它通常用于位图数据.因此,如果你使用大量的drawables,你可以很容易地运行Out Of Memory错误,即使你的JVM-Heap是大约3 MB的chillin.
dar*_*enp 20
如果您只是处理位图背景,@ hp.android的答案效果很好,但在我的情况下,我BaseAdapter
提供了一组ImageView
s用于a GridView
.我unbindDrawables()
按照建议修改了方法,以便条件是:
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
...
}
Run Code Online (Sandbox Code Playgroud)
但问题是,递归方法永远不会处理孩子的AdapterView
.为了解决这个问题,我改为做了以下事情:
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++)
unbindDrawables(viewGroup.getChildAt(i));
if (!(view instanceof AdapterView))
viewGroup.removeAllViews();
}
Run Code Online (Sandbox Code Playgroud)
以便AdapterView
仍然处理子的 - 该方法不会尝试删除所有子项(不受支持).
然而,这并没有解决问题,因为ImageView
s管理的是不是他们背景的位图.因此,我添加了以下内容.这不是理想的,但它有效:
if (view instanceof ImageView) {
ImageView imageView = (ImageView) view;
imageView.setImageBitmap(null);
}
Run Code Online (Sandbox Code Playgroud)
总的来说,unbindDrawables()
方法是:
private void unbindDrawables(View view) {
if (view.getBackground() != null)
view.getBackground().setCallback(null);
if (view instanceof ImageView) {
ImageView imageView = (ImageView) view;
imageView.setImageBitmap(null);
} else if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++)
unbindDrawables(viewGroup.getChildAt(i));
if (!(view instanceof AdapterView))
viewGroup.removeAllViews();
}
}
Run Code Online (Sandbox Code Playgroud)
我希望有一种更有原则的方法来释放这些资源.
gre*_*gkb 12
关于Android内存管理的优秀Google I/O演讲(2011),以及有关内存分析的工具+技术的详细信息:http:
//www.youtube.com/watch?v = _CruQY55HOk
嗯,这些都是与 Android 使用的独特格式挂钩的工具。我认为您可能不满意的是正在使用的底层测试代码框架。
您是否尝试过使用 Android Mock 框架来模拟测试代码区域?
归档时间: |
|
查看次数: |
93596 次 |
最近记录: |