NullPointerException in FrameLayout.onMeasure ()

9

Bearbeiten: Ich habe ein Github-Projekt erstellt, das genauso abstürzt wie meine App. Sie finden es hier

Edit: Als ich das debuggte und verschiedene Änderungen ausprobierte, merkte ich, dass der ursprüngliche Code, den ich gepostet hatte, nicht wirklich relevant war, also entfernte ich ihn:

Ich habe eine Activity , die zwischen 3 verschiedenen Fragment s wechseln kann, wenn der Benutzer einen von 3 IconButton s in einen benutzerdefinierten Layout-Layout einfügt, wie zwischen verschiedenen Modi:

Wenn ich die App zum ersten Mal starte (nachdem ich sie deinstalliert habe), bin ich standardmäßig auf den Globe-Modus eingestellt. Der Globe-Modus hat mehrere Fragmente in ViewPager , die meisten dieser Fragmente sind Unterklassen von android.support.v4.app.ListFragment . Ich erstelle alle 8 Tabs in der onCreate-Methode der Hauptaktivität. Dies funktioniert wie erwartet und alles wird ordnungsgemäß geladen.

Wenn ich in den "Profil" -Modus gehe (indem ich auf die Schaltfläche "Gesicht" klicke), kann ich mich in die App einloggen und mein Profil sehen. Dies funktioniert auch wie erwartet, alles wird korrekt geladen.

Wenn ich das APK erneut aus Android Studio dr \ u00e4cke, da ich jetzt eingeloggt bin (gespeicherte Voreinstellungen), wird der "friend feed" -Modus (die beiden Personen, die sich an den Hnden befinden) voreingestellt. Ich kann Modi zu dem Profil wechseln, und alles funktioniert wie erwartet, aber wenn ich in den Globe-Modus umschalte, stürzt es in Android-Code ab:

%Vor%

In den letzten zwei Wochen habe ich zwei wichtige Änderungen am Projekt vorgenommen:

  1. Ich habe die ActionbarSherlock-Bibliothek entfernt. Ich hatte ursprünglich gehofft, die support.v4-Bibliothek zu entfernen, bis ich merkte, dass ich sie für den ViewPager brauchte.
  2. Ich wechselte von Eclipse zu Android Studio, wozu auch das Verschieben aller Dateien in die neue Android Studio-Struktur gehörte.

Heute Morgen habe ich Eclipse neu installiert und bin direkt nach dem Entfernen von ActionbarSherlock an den Punkt gegangen und konnte diesen Absturz nicht erneut erstellen.

Dinge, die ich versucht habe:

  • Manuelles Erstellen des Projekts mit Gradle und manuelle Installation und Ausführung des Projekts. Wenn ich die gleichen Schritte mache, stürzt es auf die gleiche Weise ab.
  • Dies wird durch den Debugger ausgeführt und bei dem Absturz gestoppt. Zeile 309 ist die folgende:

    %Vor%

An dieser Stelle im Code ist child null , aber der Aufruf von getChildCount() in Zeile 296 gibt einen Wert von 2 zurück. Ich habe immer noch keine Idee, auf welche View tatsächlich abstürzt Dieser Punkt , es gibt keinen definierenden Wert in einer der Variablen, während ich sie im Debugger durchsuche.

  • Beim Anmelden / Abmelden werden Elemente im Überlaufmenü geändert. Wenn du oben auf IconButton s klickst, rufe ich setBackgroundDrawable auf den IconButtons auf, um die gelbe Markierung zu setzen (oder setze null , wenn sie nicht mehr aktiv ist). Wenn ich sowohl den Code in onCreateOptionsMenu als auch den Code in setHighlightedIconButton() auskommentiere, tritt der Absturz nicht mehr auf
  • Wenn ich alle Fragmente aus dem ViewPager entferne, tritt der Absturz nicht mehr auf
  • Als @kcoppock unten erwähnt, könnte es wahrscheinlich sein, dass ich irgendwo etwas falsch aufblase. Nach dem Artikel, den er verlinkte, änderte ich jeden Aufruf in meiner App, bei dem ich inflater.inflate(R.layout.somelayout, null) anrief, stattdessen in inflater.inflate(R.layout.somelayout, viewGroupContainer, false) , außer in dem Fall, dass ich benutzerdefinierte Ansichten auf den Registerkarten erstelle (wo ich die viewGroup nicht kenne) sie unter). In diesem Fall setze ich LayoutParameters manuell.

Ich bin an diesem Punkt völlig ratlos, was ich als nächstes noch versuchen soll.

update: Das Ändern der App auf always Start im Globe Mode verhindert den Absturz, also scheint es etwas mit dem Wechsel zum Globe Mode zu sein, wenn wir nicht t starte damit aktiv.

Hier ist mein Code, um die Tabs für den viewPager der Hauptaktivität zu erstellen:

%Vor%

Hier ist das Layout von main_browse.xml:

%Vor%

Hier ist die Funktion setHighlightedIconButton:

%Vor%

Und das ist die validateView () - Funktion, die es aufruft:

%Vor%

Hier ist onCreateOptionsMenu für die Hauptaktivität:

%Vor%

Dies ist der Teil der Funktion FrameLayout.onMeasure() , der Teil des Android API 19-Quellcodes ist, in dem er abstürzt:

%Vor%     
Carl Anderson 14.08.2014, 21:55
quelle

6 Antworten

1

Ich habe am Ende einen Fehler gegen AOSP eingereicht:

Ссылка

Die (eher knappe) Antwort, die ich dort bekommen habe, zeigt an, dass in der Funktion ViewPager.onMeasure() versucht wird, alle ausstehenden Fragment -Transaktionen auszuführen. Leider hört es sich so an, als ob das Zeigen / Verbergen der anderen Fragmente diesen Prozess stört und die NPE verursacht.

Die von ihnen empfohlene Problemumgehung bestand darin, dass ich FragmentManager.executePendingTransactions() am Ende meiner Funktion validateView() aufruft, vermutlich um die Fragmenttransaktionen, die ich festgeschrieben habe, abzuschließen, damit viewPager nicht von ihnen betroffen ist.

    
Carl Anderson 21.08.2014, 21:03
quelle
1
%Vor%

Dies ist wahrscheinlich die Ursache Ihres Problems. Wenn Sie null übergeben, weiß der Inflator nicht, welche Art von LayoutParams generiert werden soll (er generiert sie aus der übergeordneten ViewGroup). Ich glaubte, dass dies generierte Standard-ViewGroup.LayoutParams, aber vielleicht bietet es überhaupt keine LayoutParams.

Sie sollten dies ersetzen durch:

%Vor%

wobei parent die ViewGroup ist, in die customView hinzugefügt wird. Wenn Sie kein verfügbares Elternelement haben, können Sie einige benutzerdefinierte LayoutParams manuell festlegen:

%Vor%     
kcoppock 15.08.2014 18:11
quelle
1

Problem 2:

Da die Ausnahme während des Layouts ausgelöst wird, sehen zwei Aufrufe in der validateView -Methode zweifelhaft aus. Ersetzen Sie die beiden Aufrufe wie folgt: mViewPager.setVisibility(View.GONE); mit mViewPager.setVisibility(View.INVISIBLE);

Der Übergang zwischen "weg" und "sichtbar" beim Eintritt in den Globusmodus löst das Layout aus. Wenn Sie von "unsichtbar" zu "sichtbar" wechseln, wird das Layout nicht ausgelöst, und das ist eine gute Vermutung, wo eine NPE auftritt.

Aktualisierung. Basierend auf Ihrem Kommentar, nehmen wir an, dass der "gone - & gt;" - sichtbare Übergang nur eine NPE in einem anderen Layout auslöst, dh in Ihrer benutzerdefinierten Aktionsleiste.

Durch das Ablegen der Ansichtshierarchie einer Beispielanwendung (Eclipse & gt; DDMS & gt; Dump View Hierachy für View Automator), habe ich ein paar FrameLayouts in meiner Aktionsleiste gefunden, was interessant ist. Meine Beispielanwendung verwendet natürlich nicht Ihre benutzerdefinierte Ansicht, aber selbst im Symbol / home-Teil der Aktionsleiste befindet sich ein ImageView in einem Rahmenlayout.

Versuchen Sie also, diesen kniffligen Code zu ersetzen:

%Vor%

mit diesem einfacheren Code, der auf sichere Weise dasselbe tun sollte:

%Vor%

Wenn das nicht der Fall ist, sollte das Dumping der aktuellen Ansicht und die Untersuchung der FrameLayouts in Ihrer benutzerdefinierten Aktionsleiste hilfreich sein.

    
x-code 19.08.2014 14:00
quelle
0

Sie haben eine falsche ID:

%Vor%

Sie können den Punkt . char nicht verwenden.

    
asylume 14.08.2014 22:50
quelle
0

Nur eine Ahnung, aber versuchen Sie, setHighlightedIconButton (); nach dem Schalter Fall in validateView (). Dies kann dazu führen, dass die NEWS_MODE-Children instanziieren, um hoffentlich den Nullzeiger in onMeasure zu verhindern, wenn Sie den Hintergrund ändern.

    
Dave S 14.08.2014 23:53
quelle
0

Ich werde einen Stich machen. Eine Sache, die herausspringt, ist, dass das dynamische Optionsmenü auf unkonventionelle Weise implementiert wird. Sie sollten stattdessen verwenden:

%Vor%

Gefolgt von:

%Vor%

Die beiden Änderungen sind: (1) Verwenden von onPrepareOptionsMenu für dynamische Änderungen des Menüs und (2) Sicherstellen, dass die Superklasse aufgerufen wird.

Wenn ich mir meinen eigenen Code ansehe, sehe ich, dass ich die Regel (2) zuvor ohne ein Problem gebrochen habe, aber wenn der Code abstürzt, ist es einen Versuch wert.

Für Android 3+ müssen Sie invalidateOptionsMenu() aufrufen, um einen neuen Aufruf der on prepare-Methode auszulösen, aber ich sehe das bereits in Ihrem Code, also sollte es in Ordnung sein.

    
x-code 19.08.2014 03:18
quelle