0

Ich versuche, den Stil der Aktivität in Runtime zu ändern.Aktivität zur Wiederherstellung der Aktivität Ursache Nicht genügend Speicherfehler

Aber ich konfrontiert mit zunehmender verwendet Speicher während der Aktivität neu erstellen.

Für Stil zu ändern i definieren einige Themen und initialisieren int array für sich innerhalb Aktivität:

private int themes[] = new int[]{R.style.AppThemeOrange, R.style.AppThemeTeal,...}; 

Für die nächste Thema Einstellung i Thema ID in den Einstellungen und neu gestartete Aktivität gespeichert. Dann innerhalb onCreate Verfahren eingestellt i Thema von Vorlieben:

setTheme(PreferencesManager.getInstance().getAppTheme()); 

Hier ist meine Methode Thema für den Wechsel:

public void changeTheme() { 
    PreferencesManager.getInstance().setAppTheme(themes[(getCurrentThemePos() + 1) % themes.length]); 
    recreate(); 
} 

Nach jeder Neuen Aktivität zugewiesenen Speicher-Heap durch einen Wert 0.1-0.2mb erhöht. Also, wenn ich das App-Thema viele Male ändere, bekomme ich Out Of Memory Fehler. Hier ist mein Speicher Monitor:

memory monitor screen

Nur nach 1 Minute wechselnden Themen i von 10 Heap-Speicher auf 25 MB erhöht. Ich versuchte recreate() mit der Neubelebung der Aktivität mit Absicht zu ersetzen, aber das Ergebnis war das gleiche:

public void changeTheme() { 
    PreferencesManager.getInstance().setAppTheme(themes[(getCurrentThemePos() + 1) % themes.length]); 
    Intent intent = new Intent(getApplicationContext(), UsersActivity.class); 
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); 
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    finish(); 
} 

Auch habe ich versucht, alle verfügbaren Werte launchMode in AndroidManifest. Kein Effekt. Ich habe alle Vorkommen von "this" in "getApplicationContext()" geändert. Nur das Root-Layout in der XML-Datei belassen. Hier ist ein similar problem. Aber es gibt zwei Aktivitäten dort. wenn ich in meinem Fall verwenden

Intent i = new Intent(getApplicationContext(), UsersActivity.class); 
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 
startActivity(i); 

Aktivität wieder aufs Neue schafft nicht der Fall, da es bereits sichtbar ist, und onCreate() nicht aufgerufen wird und das Thema wird nicht verändert. Ich habe auch versucht, System.gc(); in onDestroy() aufzurufen, aber Speicherverbrauch erhöht sowieso.

Hier Fragment meiner styles.xml Datei:

<style name="ChangebleTheme" parent="Theme.AppCompat.Light.NoActionBar"> 
    <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item> 
    <item name="android:editTextStyle">@style/EditTextStyle</item> 
    <item name="editTextStyle">@style/EditTextStyle</item> 
    <item name="android:buttonStyle">@style/ButtonStyle</item> 
    <item name="buttonStyle">@style/ButtonStyle</item> 
    <item name="android:checkboxStyle">@style/CheckboxStyle</item> 
    <item name="checkboxStyle">@style/CheckboxStyle</item> 
    <item name="switchStyle">@style/SwitchStyle</item> 
    <item name="alertDialogProTheme">@style/Theme.AlertDialogPro.Material.Light</item> 
</style> 

<style name="AppThemeOrange" parent="ChangebleTheme"> 
    <item name="main_theme_color">@color/colorAccentOrange</item> 
    <item name="main_theme_color_dark">@color/colorAccentDarkOrange</item> 
    <item name="colorAccent">@color/colorAccentOrange</item> 
    <item name="colorPrimaryDark">@color/colorAccentDarkOrange</item> 
    <item name="android:navigationBarColor">@color/colorAccentOrange</item> 
    <item name="ab_divider_style">@style/AppThemeOrange.ActionBarDivider</item> 
</style> 

<style name="AppThemeTeal" parent="ChangebleTheme"> 
    <item name="main_theme_color">@color/colorAccentTeal</item> 
    <item name="main_theme_color_dark">@color/colorAccentDarkTeal</item> 
    <item name="colorAccent">@color/colorAccentTeal</item> 
    <item name="colorPrimaryDark">@color/colorAccentDarkTeal</item> 
    <item name="android:navigationBarColor">@color/colorAccentTeal</item> 
    <item name="ab_divider_style">@style/AppThemeTeal.ActionBarDivider</item> 
</style> 

FRAGE:

Kann jemand mir zeigen, was ich falsch mache und wie kann ich die Speichernutzung verhindern zu erhöhen? Oder gibt es vielleicht eine bessere Möglichkeit, den Stil der App in Runtime zu ändern?

Vielen Dank im Voraus!

+1

In Android ist es super einfach Aktivitäten zu lecken. Verwenden Sie AsyncTasks oder Handlers Haben Sie irgendwelche Singletons, die einen Context enthalten? – CaseyB

+1

Wird der Speicher-Footprint auch auf die gleiche unbeschränkte Weise wachsen, wenn Sie einfach das Gerät drehen, ohne Ihren Theme-Switching-Code aufzurufen? Außerdem, da Sie die gleiche Aktivität neu starten, schätze ich Du kannst nur mit 'android: launchMode =" singleTop "' auskommen, und du brauchst nicht 'Intent.FLAG_ACTIVITY_REORDER_TO_FRONT'. Hilft das? – theFunkyEngineer

+0

Danke für deine schnellen Antworten! @CaseyB Ich benutze wirklich AsyncTasks und Handler in meinem Code , aber zum Testen kam ich al l Code, der nur 'setTheme'- und' setContentView'-Methoden zurücklässt. @theFunkyEngineer Rotierende Geräte verursachen die gleiche Situation. Dank Ihrer Antworten habe ich versucht, ein völlig neues Projekt zum Testen zu erstellen. Wenn ich default created xml layout nutze, wächst nach dem Neuerstellen des activity memory, aber nach einigen Malen kehrt es zum Anfangszustand zurück (ungefähr 11mb). Wenn ich mein vorheriges XML-Layout in ein neues Projekt lege, kommt das Problem zurück. Also ich denke, ich habe schlechte Layout-Verwaltung. Ich werde meine Frage mit mehr Informationen aktualisieren! – MatWay

Antwort

0

Vielen Dank für Ihre Hilfe!

Bei der Überprüfung Detail Code fand ich 2 Dinge, das Speicherleck verursacht:

1) In meiner XML-Datei welche ich verwenden 3rd-Party-Ansicht (AVLoadingIndicatorView) nicht entfernt Animateure in onDetachedFromWindow() Methode. Auch habe ich festgestellt, dass einige andere Fortschrittsbalken von Drittanbietern die Animationen nach dem Abnehmen nicht löschen.

2) Ich hatte Handler innerhalb Adapter (das ist alles meine Unaufmerksamkeit :(), die ich aufhören und klar nicht vor Aktivität zu zerstören.