【发布时间】:2012-03-05 09:03:30
【问题描述】:
我的代码在方向更改时出现大量内存泄漏。旋转手机一次或两次后堆已满。我试图追踪泄漏两天了,但没有成功。
应用程序使用 SDK 15(最少 14 个)。
MainActivity 显示一个带有列表导航的 ActionBar (NAVIGATION_MODE_LIST)。导航微调器会替换显示的片段。
代码有效。
ListNavigationItem,其中包含实例化 Fragments 所需的信息:
public class ListNavigationItem
{
public final String fragmentClass;
public final String title; // Used as fragment tag and as title
public ListNavigationItem(String fragmentClass, String title)
{
this.fragmentClass = fragmentClass;
this.title = title;
}
@Override
public String toString()
{
return title;
}
}
最后是我的(简化版)MainActivity:
public class MainActivity extends Activity implements OnNavigationListener
{
private MyApplication app;
private ArrayAdapter<ListNavigationItem> adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
app = (MyApplication) getApplicationContext();
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
adapter = new ArrayAdapter<ListNavigationItem>(this, android.R.layout.simple_spinner_dropdown_item);
adapter.add(new ListNavigationItem(FirstFragment.class.getName(), "First"));
adapter.add(new ListNavigationItem(SecondFragment.class.getName(), "Second"));
actionBar.setListNavigationCallbacks(adapter, this);
}
public boolean onNavigationItemSelected(int itemPosition, long itemId)
{
ListNavigationItem item = adapter.getItem(itemPosition);
if (item == null)
return false;
Fragment f = getFragmentManager().findFragmentByTag(item.title);
if (f == null)
f = Fragment.instantiate(this, item.fragmentClass);
else if (f.isAdded())
return true;
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.replace(R.id.main_content, f, item.title);
fragmentTransaction.commit();
return true;
}
@Override
protected void onDestroy()
{
adapter = null; // Do I need this?
app = null;
super.onDestroy();
}
}
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="at.company.app"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="14" />
<uses-sdk android:targetSdkVersion="15" />
<application
android:name=".Application"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity
android:name=".MainActivity"
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>
MAT 堆分析表明,android.content.res.Resources 类占用了 57% 的可用内存,android.graphics.Bitmap 占用了 12%。然而,我的片段只包含一个简单的TextView。
MAT 直方图显示MainActivity 有 4 个对象(我假设是实例?)。此外,logcat 显示在方向更改 (GC_CONCURRENT) 后堆经常被清空。
官方开发指南不鼓励使用android:configChanges="orientation"。 (Source)
我对 Java 和 Android 平台比较陌生,如果能提供任何帮助,我将不胜感激。
【问题讨论】:
标签: android memory-leaks android-fragments android-4.0-ice-cream-sandwich