2015-04-22 7 views
60

erzeugen Ich verwende eine Symbolleiste als meine Aktionsleiste in einer Aktivität. Ich versuche, die Methode getActionBar().setDisplayHomeAsUpEnabled(true); der Activity.java-Datei für Up-Navigation für ältere Geräte hinzuzufügen.Wie die getActionBar-Methode repariert wird, kann java.lang.NullPointerException

Das Verfahren erzeugt die folgende Fehlermeldung in Android Studio:

Methodenaufruf java.lang.NullPointerException produzieren kann

Die Up-Navigation auf der Symbolleiste funktioniert auf neueren Geräten in Ordnung ... Jetzt versuche ich herauszufinden, wie ich sicherstellen kann, dass es für ältere Geräte funktioniert. Bitte beraten.

Von build.gradle:

dependencies { 
    compile "com.android.support:appcompat-v7:22.1.0" 
} 

Von AndroidManifest.xml:

android:theme="@style/Theme.AppCompat.NoActionBar.FullScreen" 

Von styles.xml

<style name="Theme.AppCompat.NoActionBar.FullScreen" parent="AppTheme"> 
<item name="android:windowNoTitle">true</item> 
<item name="windowActionBar">false</item> 
<item name="android:windowFullscreen">true</item> 

von Activity.java

public class CardViewActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.cardviewinput); 

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 

    if (toolbar != null) { 
     // Up navigation to the parent activity for 4.0 and earlier 
     getActionBar().setDisplayHomeAsUpEnabled(true); 
     toolbar.setNavigationIcon(R.drawable.ic_action_previous_item); 
     toolbar.setNavigationOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       onBackPressed(); 
      } 
     }); 
    } 

} 
+1

Ist das nicht Ihr Thema ein, das keine ActionBar hat? – juunas

Antwort

102

Eigentlich Android Studio zeigt Ihnen keine "Fehlermeldung" Es ist nur eine Warnung.

Einige Antworten schlagen die Verwendung einer Behauptung vor, Dalvik Runtime hat assertion standardmäßig deaktiviert, so dass Sie es tatsächlich einschalten müssen, damit es tatsächlich etwas tut. In diesem Fall (die Assertion ist deaktiviert) täuschen Sie im Grunde nur Android Studio, um Ihnen die Warnung nicht anzuzeigen. Außerdem bevorzuge ich es, im Produktionscode nicht "assert" zu verwenden.

Meiner Meinung nach, was Sie tun sollten, ist sehr einfach.

if(getActionBar() != null){ 
    getActionBar().setDisplayHomeAsUpEnabled(true); 
} 

Update: Falls Sie sich die Support-Bibliothek Version der Aktionsleiste verwenden, sollten Sie ersetzen getActionBar() mit getSupportActionBar().

if(getSupportActionBar() != null){ 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
} 
+2

Während ich ursprünglich verwendet habe, um die Warnung zu "lösen", stimme ich zu, dass Ihr empfohlener Code besser ist als der Assert-Hack. Die Antwort wurde aktualisiert und akzeptiert. Beachten Sie, dass ich AppCompatActivity als Klasse verwende, sodass ich getSupportActionBar() in meiner Lösung anstelle der oben gezeigten getActionBar() verwenden muss. – AJW

+2

Warum Android Studio nicht die gleiche Warnung für andere Methoden wie getSupportActionBar() geben. SetTitle()? –

+0

Ich benutze die getSupportActionBar()! = Null, aber ich bin immer noch ein Null-Zeiger auf meiner Symbolleiste geworfen. Weiß jemand was los ist? Ich habe versucht, die Assert-Zeile, die auch nur einen Nullzeiger wirft! Was ist los!??!?!?! – ZooMagic

33

Zunächst müssen Sie die Symbolleiste als die Unterstützung ActionBar festlegen. Dann, wenn Sie sicher sind, dass es die ganze Zeit da sein wird, nur behaupten Sie es als! = Null. Dies sagt dem Compiler, dass es nicht null sein wird, so dass der Null-Check bestanden wird.

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.cardviewinput); 

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    assert getSupportActionBar() != null; 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); // it's getSupportActionBar() if you're using AppCompatActivity, not getActionBar() 
} 
+0

Ok, sieht gut aus, aber die Assert-Zeile erzeugt in Android Studio ein "Can not resolve symbol 'getSupportActionBar'" Fehler. Sollte es "getSupportActionBar()" sein? Bitte beraten. – AJW

+0

Sie können nur auf getSupportActionBar zugreifen, wenn Sie AppCompatActivity oder FragmentActivity erweitern – Sheychan

8

Vielen Dank Andrew für Ihre Antwort. Wenn Sie ein Nav-Drawer oder etwas anderes haben, das getSupportActionBar() verwendet, müssen Sie das assert getSupportActionBar()! = Null;

Frieden,

Beispiel:

@Override 
public void setTitle(CharSequence title) { 
    mTitle = title; 
    assert getSupportActionBar() != null; 
    getSupportActionBar().setTitle(mTitle); 
} 
+3

Gilt dies für die Produktion oder nur zum Testen? – gian1200

+0

gian1200 Ich bin mir nicht sicher. Eine gute Frage. Ich hatte vor, meine App bald zu veröffentlichen, also werde ich recherchieren, bevor ich die Veröffentlichung mache ... Thx. – Scott

+0

Meine Vermutung ist, dass der Compiler es in etwas wie "wenn es null ist, dann werfen Sie eine assertExeption" ändern; Ihnen nicht erlauben, den Fehler zu behandeln. – gian1200

4

Try this:

private ActionBar getActionBar() { 
    return ((AppCompatActivity) getActivity()).getSupportActionBar(); 
} 
2

hinzufügen assert getSupportActionBar() != null; vor getSupportActionBar().setDisplayHomeAsUpEnabled(true);

3

Was ich getan habe ist die getSupportActionBar() Methode in meiner Basisaktivität außer Kraft setzen und eine @NonNull Anmerkung hinzuzufügen. Auf diese Weise erhalte ich in der Basisaktivität nur eine einzige Warnmeldung darüber, wie ich @NonNull Annotation für etwas verwende, das eine @Nullable Annotation hat.

@NonNull 
    @Override 
    public ActionBar getSupportActionBar() { 
     // Small hack here so that Lint does not warn me in every single activity about null 
     // action bar 
     return super.getSupportActionBar(); 
    } 
+0

danke für deine antwort. Ich weiß nicht, ob ich Flusen benutze. Kannst du irgendeinen Vorteil gegenüber Adam Ghanis Antwort oben erklären? – AJW

+0

Mit Adams Ansatz müssen Sie die if-Anweisung in alle Ihre Aktivitäten schreiben. Bei meinem Ansatz müssen Sie nur die getSupportActionBar in der Basisaktivität überschreiben und der Rest des Codes bleibt wie zuvor. –

1

Ich habe eine generische Klasse wie:

public final class Cast 
{ 
    private Cast() {} 

    /** 
    * Helps to eliminate annoying NullPointerException lint warning. 
    */ 
    @android.support.annotation.NonNull 
    public static <T> T neverNull(T value) 
    { 
     return value; 
    } 
} 

dann kann ich es für jeden Anruf mit Nullpointer Warnung verwenden, für die ich bin sicher, dass es nie passieren wird, z.B.

final ActionBar actionBar = Cast.neverNull(getSupportActionBar()); 
actionBar.setDisplayHomeAsUpEnabled(true); 
actionBar.setHomeButtonEnabled(true); 

P.S. Vergessen Sie nicht, "com.android.support:support-annotations" zu Ihrer Gradle-Datei hinzuzufügen.

0
if(actionBar != null) { 
    actionBar.setHomeButtonEnabled(true); 
    actionBar.setBackgroundDrawable(ContextCompat.getDrawable(mContext, 
            R.drawable.action_bar_gradient)); 
} 
0

Verwendung dieses Thema: android:theme="@style/Theme.AppCompat.Light.NoActionBar"

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
toolbar.setTitle("Title"); 
setSupportActionBar(toolbar); 
ActionBar actionBar = getSupportActionBar(); 
actionBar.setHomeButtonEnabled(true); 
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_previous_item); 
actionBar.setDisplayHomeAsUpEnabled(true); 
Verwandte Themen