Das Beheben der getActionBar-Methode kann zu einer java.lang.NullPointerException führen

73

Ich verwende eine Symbolleiste als Aktionsleiste in einer Aktivität. Ich versuche, die Methode getActionBar().setDisplayHomeAsUpEnabled(true);zur Datei Activity.java für die Up-Navigation für ältere Geräte hinzuzufügen .

Die Methode erzeugt in Android Studio die folgende Fehlermeldung:

Der Methodenaufruf kann zu einer java.lang.NullPointerException führen

Die Aufwärtsnavigation in der Symbolleiste funktioniert auf neueren Geräten einwandfrei. Jetzt versuche ich herauszufinden, wie sichergestellt werden kann, dass sie auf älteren Geräten funktioniert. Bitte beraten.

Von build.gradle:

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

Aus AndroidManifest.xml:

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

Aus 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();
            }
        });
    }

}
AJW
quelle
1
Ist Ihr Thema nicht eines, das keine ActionBar hat?
Juunas

Antworten:

127

Tatsächlich zeigt Android Studio keine "Fehlermeldung" an, sondern nur eine Warnung.

Einige Antworten schlagen die Verwendung einer Zusicherung vor. Die Dalvik-Laufzeit hat die Zusicherung standardmäßig deaktiviert, sodass Sie sie tatsächlich einschalten müssen, damit sie tatsächlich etwas bewirkt. In diesem Fall (Zusicherung ist deaktiviert) betrügen Sie Android Studio im Wesentlichen nur, um Ihnen die Warnung nicht anzuzeigen. Außerdem bevorzuge ich es, "assert" nicht im Produktionscode zu verwenden.

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

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

Update: Wenn Sie die Support-Bibliotheksversion der Aktionsleiste verwenden, sollten Sie getActionBar () durch getSupportActionBar () ersetzen.

if(getSupportActionBar() != null){
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
Adam Ghani
quelle
2
Während ich Assert 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 positiv bewertet und akzeptiert. Beachten Sie, dass ich AppCompatActivity als Klasse verwende, daher muss ich getSupportActionBar () in meiner Lösung anstelle der oben gezeigten getActionBar () verwenden.
AJW
4
Warum gibt Android Studio nicht die gleiche Warnung für andere Methoden wie getSupportActionBar (). SetTitle ()?
Piyush Kukadiya
Ich verwende die getSupportActionBar ()! = Null, aber ich habe immer noch einen Nullzeiger auf meiner Symbolleiste. Weiß jemand was los ist? Ich habe die Assert-Zeile ausprobiert, die auch nur einen Nullzeiger auslöst! ??! Was ist los!??!?!?!
ZooMagic
@ZooMagic Es gibt verschiedene Gründe, warum es eine NPE werfen könnte. Ich rate Ihnen, nach anderen Fragen zu suchen, die Ihren ähnlich sind, oder Ihren Code auf eine neue Frage zu setzen. Sie müssen Ihre Layoutdatei, Ihr Manifest und Ihren Aktivitätscode freigeben.
Adam Ghani
34

Zunächst müssen Sie die Symbolleiste als unterstützende Aktionsleiste festlegen. Wenn Sie sicher sind, dass es die ganze Zeit dort sein wird, behaupten Sie es einfach als! = Null. Dies teilt dem Compiler mit, dass es nicht null sein wird, sodass die Nullprüfung 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()
}
Bogdan Zurac
quelle
Ok, sieht gut aus, aber die Assert-Zeile generiert in Android Studio den Fehler "Symbol 'getSupportActionBar' kann nicht aufgelöst werden". Sollte es "getSupportActionBar ()" sein? Bitte beraten.
AJW
1
Sie können nur auf getSupportActionBar zugreifen, wenn Sie AppCompatActivity oder FragmentActivity
Sheychan
8

Danke Andrew für deine Antwort. Wenn Sie eine Navigationsleiste oder etwas anderes haben, das getSupportActionBar () verwendet, müssen Sie assert getSupportActionBar () hinzufügen! = Null;

Frieden,

Beispiel:

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    assert getSupportActionBar() != null;
    getSupportActionBar().setTitle(mTitle);
}
Scott
quelle
3
Gilt dies für die Produktion oder nur zum Testen?
gian1200
gian1200 Ich bin nicht sicher. Eine gute Frage. Ich hatte vor, meine App bald zu veröffentlichen, also werde ich vor der Veröffentlichung Nachforschungen anstellen ... Danke.
Scott
Ich vermute, dass der Compiler es in etwas wie "Wenn es null ist, dann werfen Sie eine assertExeption" ändern wird; Sie können den Fehler nicht behandeln.
Gian1200
4

Versuche dies :

private ActionBar getActionBar() {
    return ((AppCompatActivity) getActivity()).getSupportActionBar();
}
Shubham A.
quelle
3

Ich habe die getSupportActionBar()Methode in meiner Basisaktivität überschrieben und eine @NonNullAnmerkung hinzugefügt . Auf diese Weise erhalte ich in der Basisaktivität nur eine Flusenwarnung darüber, wie ich @NonNullAnmerkungen für etwas verwende, das eine @NullableAnmerkung enthält.

    @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();
    }
Catalin Morosan
quelle
Danke für deine Antwort. Ich weiß nicht, wie man Flusen verwendet. Können Sie einen Vorteil kommentieren, den Ihre Antwort gegenüber der Antwort von Adam Ghani oben hat?
AJW
Mit Adams Ansatz müssen Sie die if-Anweisung in all Ihren 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.
Catalin Morosan
3

Ich habe eine generische Klasse erstellt 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 Aufruf mit NullPointerException-Warnung verwenden, für den ich sicher bin, dass es niemals passieren wird, z

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

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

unterbrechen
quelle
2

assert getSupportActionBar() != null;vorher hinzufügengetSupportActionBar().setDisplayHomeAsUpEnabled(true);

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

Verwenden Sie 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);
Surendran
quelle
0

Alternativ können Sie die Aktionsleiste auf null setzen. Fügen Sie die Zusicherung hinzu, bevor Sie die Aktionsleiste wie folgt aufrufen

assert getSupportActionBar() != null;

Das endgültige Snippet würde daher wie folgt aussehen:

    setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
    assert getSupportActionBar() != null;
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
RileyManda
quelle
0

Versuche dies :

setSupportActionBar (toolbar);
if(getSupportActionBar () != null) {
assert getSupportActionBar () != null;
getSupportActionBar ().setDisplayHomeUpEnabled(true);
}

Beachten Sie, dass setSupportActionBar (Symbolleiste) vor getSupportActionBar () stehen sollte.

Saibhaskar
quelle
0
  if(getSupportActionBar() != null){
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
    OR

Ersetzen Sie die MainActivity extends AppCompatActivityzupublic class MainActivity extends AppCompatActivity

MEGHA DOBARIYA
quelle
0

Überprüfen Sie einfach getSupportActionBar ungleich null

    setSupportActionBar(toolbar);

    if(getSupportActionBar() != null) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Daily Shopping List");
    }
Salahuddin
quelle
0

Wenn Sie importieren

android.app.ActionBar 

Sie müssen getActionBar () verwenden

und wenn Sie importieren

android.support.v7.app.ActionBar

benutze getSupportActionBar ()

MN. Vala
quelle