Cómo arreglar el método getActionBar puede producir java.lang.NullPointerException

6 minutos de lectura

avatar de usuario
AJW

Estoy usando una barra de herramientas como barra de acción en una actividad. Estoy tratando de agregar el método getActionBar().setDisplayHomeAsUpEnabled(true); al archivo Activity.java para la navegación hacia arriba para dispositivos más antiguos.

El método genera el siguiente mensaje de error en Android Studio:

La invocación del método puede producir java.lang.NullPointerException

La navegación hacia arriba en la barra de herramientas funciona bien en los dispositivos más nuevos… ahora estoy tratando de descubrir cómo asegurarme de que funcione para los dispositivos más antiguos. Por favor avise.

Desde build.gradle:

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

De AndroidManifest.xml:

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

Desde estilos.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>

de Actividad.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();
            }
        });
    }

}

  • ¿Tu tema no es uno que no tiene una ActionBar?

    – juunas

    22 de abril de 2015 a las 1:25

avatar de usuario
Adán G.

En realidad, Android Studio no le muestra un “mensaje de error”, es solo una advertencia.

Algunas respuestas proponen el uso de una aserción, el tiempo de ejecución de Dalvik tiene la aserción desactivada de forma predeterminada, por lo que debe activarla para que realmente haga algo. En este caso (la afirmación está desactivada), lo que básicamente está haciendo es engañar a Android Studio para que no le muestre la advertencia. Además, prefiero no usar “afirmar” en el código de producción.

En mi opinión, lo que debes hacer es muy simple.

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

Actualizar:
En caso de que esté utilizando la versión de la biblioteca de soporte de la barra de acción, debe reemplazar getActionBar() con getSupportActionBar().

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

  • Si bien originalmente usé la afirmación para “resolver” la advertencia, estoy de acuerdo en que su código recomendado es mejor que el truco de afirmación. La respuesta ha sido votada y aceptada. Tenga en cuenta que estoy usando AppCompatActivity como clase, por lo que debo usar getSupportActionBar() en mi solución en lugar de getActionBar() que muestra arriba.

    – AJW

    3 de marzo de 2016 a las 2:02

  • ¿Por qué Android Studio no da la misma advertencia para otros métodos como getSupportActionBar().setTitle() ?

    – Piyush Kukadiya

    5 de mayo de 2017 a las 6:30

  • ¡Estoy usando getSupportActionBar() != null pero todavía recibo un puntero nulo en mi barra de herramientas. ¿Alguien sabe qué está pasando? ¡He probado la línea de aserción, que también arroja un puntero nulo! ¡¿¡¿¡¿¿¡Que esta pasando!??!?!?!

    – ZooMagic

    1 de marzo de 2018 a las 9:51

  • @ZooMagic Hay diferentes razones por las que podría arrojar un NPE. Le aconsejo que busque otras preguntas que sean similares a la suya o publique su código en una nueva pregunta. Debe compartir su archivo de diseño, manifiesto y código de actividad.

    – Adán G.

    1 de marzo de 2018 a las 18:57

avatar de usuario
Bogdan Zurac

En primer lugar, debe configurar la barra de herramientas como ActionBar de soporte. Luego, si está seguro de que estará allí todo el tiempo, simplemente asegúrelo como != nulo. Esto le dirá al compilador que no será nulo, por lo que pasa la verificación nula.

@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()
}

  • Vale, se ve bien, pero la línea de aserción genera el error “No se puede resolver el símbolo ‘getSupportActionBar'” en Android Studio. ¿Debería ser “getSupportActionBar()”? Por favor avise.

    – AJW

    23 de abril de 2015 a las 22:19


  • Solo puede acceder a getSupportActionBar cuando extiende AppCompatActivity o FragmentActivity

    – Shey-chan

    5 de agosto de 2015 a las 8:49

Gracias Andrés por tu respuesta. Si tiene un cajón de navegación o cualquier otra cosa que use getSupportActionBar(), debe agregar la afirmación getSupportActionBar() != null;

Paz,

Ejemplo:

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

  • ¿Esto es válido para producción, o solo para pruebas?

    – gian1200

    26 de abril de 2015 a las 1:22

  • gian1200 No estoy seguro. una buena pregunta Estaba planeando lanzar mi aplicación pronto, así que investigaré antes de hacer el lanzamiento… Gracias.

    – Scott

    28 de abril de 2015 a las 0:05


  • Mi suposición es que el compilador lo cambiará a algo como “si es nulo, entonces lanzará una afirmación de excepción”; no le permite manejar el error.

    – gian1200

    28 de abril de 2015 a las 0:15


Prueba esto :

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

Lo que he hecho es anular el getSupportActionBar() método en mi actividad base y agregar un @NonNull anotación. De esta manera, solo recibo una advertencia de pelusa en la actividad base sobre cómo uso @NonNull anotación para algo que tiene un @Nullable anotación.

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

  • gracias por tu respuesta. No sé sobre el uso de pelusa. ¿Puede comentar alguna ventaja que tenga su respuesta frente a la respuesta de Adam Ghani arriba?

    – AJW

    1 de abril de 2016 a las 2:14

  • Con el enfoque de Adam, debe escribir la instrucción if en todas sus actividades. Con mi enfoque, solo tiene que anular getSupportActionBar en la actividad base y el resto del código permanece como antes.

    – Catalín Morosan

    2 de abril de 2016 a las 5:32

avatar de usuario
interrumpir

Creé una clase genérica como:

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;
    }
}

entonces puedo usarlo para cualquier llamada con advertencia NullPointerException para la cual estoy seguro de que nunca sucederá, por ejemplo

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

PD: no olvide agregar “com.android.support:support-annotations” a su archivo gradle.

  • gracias por tu respuesta. No sé sobre el uso de pelusa. ¿Puede comentar alguna ventaja que tenga su respuesta frente a la respuesta de Adam Ghani arriba?

    – AJW

    1 de abril de 2016 a las 2:14

  • Con el enfoque de Adam, debe escribir la instrucción if en todas sus actividades. Con mi enfoque, solo tiene que anular getSupportActionBar en la actividad base y el resto del código permanece como antes.

    – Catalín Morosan

    2 de abril de 2016 a las 5:32

avatar de usuario
nikos

agregar assert getSupportActionBar() != null; antes de getSupportActionBar().setDisplayHomeAsUpEnabled(true);

¿Ha sido útil esta solución?