我发现很少有主题描述类似的问题,但没有找到由非常简单的Android应用程序创建的内存泄漏解决方案:
的AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cz.reloecc.testBackground"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10"/>
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher">
<activity android:name="TestBackgroundActivity"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
的 main.xml中 :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/ui">
</LinearLayout>
的 TestBackgroundActivity.java :
public class TestBackgroundActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
在更改我的设备的方向时(nvidia Tegra Note 7),logcat注意到:
cz.reloecc.testBackground I/dalvikvm-heap﹕ Grow heap (frag case) to 35.625MB for 12904976-byte allocation
每次周转时大约增加13MB(对于最大版本的图像)
直到我的堆最大值(64MB):
cz.reloecc.testBackground E/dalvikvm-heap﹕ Out of memory on a 12904976-byte allocation.
cz.reloecc.testBackground I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
..
cz.reloecc.testBackground I/dalvikvm﹕ at cz.reloecc.testBackground.TestBackgroundActivity.onCreate(TestBackgroundActivity.java:13)
的 BUT!
当我从 drawable-land- [x | m | l] dpi 或 drawable-删除ui.png(设置为背景)时,不问题仍然存在res文件夹中的[x | m | l] dpi 文件夹..
所以,如果我只有一个版本的背景图片,我可以将设备转了一周...
这是我的问题:如何处理多个版本的drawables(设置为背景)以避免内存泄漏?
//编辑:我很少尝试处理,回收,销毁,归零资源或其持有者,最后一个是基于Aeshang的建议:
=== 版本2.0 ===
Resources.java :
public class Resources {
public Resources(Context context){
this.context = context;
}
public Drawable getImage(int id){
if(images.indexOfKey(id) < 0){
Drawable drawable = context.getResources().getDrawable(id);
images.put(id, drawable);
}
return images.get(id);
}
public void disposeImages(){
int key;
for(int i = 0; i < images.size(); i++) {
key = images.keyAt(i);
Drawable drawable = images.get(key);
if(drawable instanceof BitmapDrawable){
if(drawable instanceof BitmapDrawable){
Log.i(TestBackgroundActivity.LOG_TAG, "Recycling image " + key);
((BitmapDrawable)drawable).getBitmap().recycle();
}
}
}
}
public void disposeAll(){
disposeImages();
images.clear();
}
private SparseArray<Drawable> images = new SparseArray<Drawable>();
private Context context;
}
的 TestBackgroundActivity.java :
public class TestBackgroundActivity extends Activity {
public static String LOG_TAG = "[TestBG]";
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resources = new Resources(getApplicationContext());
LinearLayout mainLayout = (LinearLayout)findViewById(R.id.mainLayout);
mainLayout.setBackgroundDrawable(resources.getImage(R.drawable.ui));
}
@Override
protected void onDestroy(){
resources.disposeAll();
super.onDestroy();
}
private Resources resources;
}
答案 0 :(得分:0)
使用第三方库加载drawables
如Picasso或Universal Image Loader
他们将自动处理大型位图
来到drawables
用户1920X1080分辨率图像并将它们放在drawable-xxhdpi文件夹中,每件事情都可以正常工作
答案 1 :(得分:0)
确定,
这绝对有用。测试了另外两个设备,并且altrough app抱怨高内存堆增长。它就是gc'ing。
我的tegra Note 7是痛苦。我将不得不找到这个地狱的正确来源。
//编辑: 好的,打电话
System.gc();
在MainActivity的onDestroy()
中和app永远持续......谁知道为什么?