Мой код имеет значительную утечку памяти при изменении ориентации.Куча полна после поворота телефона один или два раза.Я пытался отследить утечку в течение двух дней безуспешно.
Приложение использует SDK 15 (мин. 14).
MainActivity
показывает панель действий с навигацией по списку (NAVIGATION_MODE_LIST
),Навигация по счетчику заменяет показанный фрагмент.
Код работает.
ListNavigationItem
, который содержит информацию, необходимую для создания экземпляров фрагментов:
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 показывает, что существует 4 объекта (экземпляры, я полагаю?) С MainActivity
.Кроме того, logcat показывает, что куча часто очищается после изменения ориентации (GC_CONCURRENT).
Официальное руководство разработчика не рекомендует использовать android:configChanges="orientation"
.( Source )
Я относительно новичок в Java и платформе Android, и я был бы признателен за любую помощь.