web-dev-qa-db-fra.com

Manière appropriée de gérer Android Avertissement de peluches NullPointerException de Studio

Je suis nouveau dans la programmation Android/Java et je ne sais pas comment gérer correctement cet avertissement.

L'appel de méthode '' peut produire 'Java.lang.NullPointerException'

enter image description here

Dois-je utiliser assert pour supprimer l'avertissement? enter image description here

Ou plutôt une exception d'exécution? enter image description here

Toute aide serait appréciée.

33
Hackmodford

Je doute que cette question puisse trouver une réponse définitive, car c'est une question d'opinion. Ou du moins je le crois - une opinion aussi. :)

Je comprends que vous voulez "0 avertissements" (un objectif très louable) mais il n'y a probablement pas de problème "taille unique". Cela dit...

Ce que je pense que vous ne devriez pas faire:

  • Utilisez assert . Bien que vous puissiez ajouter une déclaration d'assertion, Dalvik les ignore. Vous pouvez configurer un émulateur pour les utiliser si vous le souhaitez, mais pas un véritable appareil (voir Puis-je utiliser assert sur Android devices? ). supprimer l'avertissement, c'est inutile en pratique.
  • Demandez à la méthode de lancer NullPointerException. Ce serait une mauvaise idée, en général. Dans ce cas, puisque vous êtes probablement prioritaireonOptionsItemSelected(), ce n'est même pas possible.

Vérification de (variable != null) est généralement la meilleure approche. Que faire si c'est le cas, cependant, présente d'autres options.

  • Si c'est un problème, vous pouvez récupérer à partir de, c'est-à-dire que vous pouvez continuer l'application même si le searchView n'est pas là, faites-le. Par exemple, revenez simplement de la méthode. C'est une bonne idée de consigner cette situation, donc vous pouvez la repérer pendant le test.
  • Sinon, si la poursuite n'est pas possible, lancez une exception. Vous voulez échouer tôt , afin que le problème puisse être facilement détecté. Une exception raisonnable dans ce cas serait IllegalStateException (voir équivalent Java à .NET System.InvalidOperationException ). Il indique essentiellement que cette méthode a été exécutée à un moment inapproprié. Attention cependant, en tant que RuntimeException, ces exceptions ne sont pas vérifiées et entraîneront probablement le blocage de l'application.
28
matiash

J'ai commencé à utiliser

@SuppressWarnings("ConstantConditions")

sur des méthodes simples où je suis sûr que l'id n'est pas nul.

25
Herrbert74

Ce que @ Herrbert74 a suggéré qu'il fonctionnait sûrement bien, mais parfois il vaut mieux ne pas ajouter de @SuppressWarnings("ConstantConditions") à une méthode entière (si ce n'est pas trivial), une meilleure approche pourrait être d'utiliser //noinspection ConstantConditions Sur le ligne avertie.

Ce sont mes règles d'or:

  • Utilisez @SuppressWarnings("ConstantConditions") lorsque la méthode est simple

  • Utilisez //noinspection ConstantConditions Lorsque la méthode est complexe et que vous devez supprimer l'avertissement uniquement sur une ligne spécifique

4
MatPag

Personnellement, je préfère utiliser try {} catch {} simplement parce qu'il est plus élégant. Cependant, cela ajoute beaucoup de volume à votre code, si vous imaginez mettre toutes les valeurs NULL possibles dans une prise d'essai (si elles ne sont pas côte à côte)

1
Georgi Angelov

Comme l'a souligné @matiash, il n'existe pas de solution unique.

Pour moi, un bon compromis était de désactiver l'avertissement NullPointerException pour tous les appels à findViewById() et de le conserver pour les autres appels de méthode. De cette façon, je prends la responsabilité de vérifier les identifiants de ressource, mais j'obtiens toujours un avantage d'obtenir des avertissements si je fais d'autres erreurs.

Pour ce faire, j'ai ajouté _ -> !null contrat de méthode avec Android Menu de réparation rapide de Studio.

L'action a généré un fichier suivant à Android/support/v7/app/annotations.xml dans la racine de mon projet.

<root>
  <item name='Android.support.v7.app.AppCompatActivity Android.view.View findViewById(int)'>
    <annotation name='org.jetbrains.annotations.Contract'>
      <val val="&quot;_ -&gt; !null&quot;" />
    </annotation>
  </item>
</root>

Mise à jour: Malheureusement, il ne survit pas Android Studio redémarre :-( Les ​​annotations externes sont vraiment utiles, donc j'espère que je trouverai un moyen de faire Android Studio les charge après le redémarrage.

1
Iwo Banas

Oui. Utiliser if (Object != null){} pour valider est la bonne façon. try {} catch (NullPointerException) {} est la solution suivante préférée dans ce cas.

Si vous voulez vous en débarrasser, lancez un NullPointerException. Lint l'ignorera dans ce cas. public void myFunc() throws NullPointerException{}.

Quoi qu'il en soit, un bon codage signifie toujours tout valider pour un problème possible lors de l'exécution. Validation != null est très bien et doit toujours être utilisé chaque fois qu'il est possible null.

1
Emanuel S

J'aime la réponse à cette lien .

L'avertissement n'est pas une erreur. Et l'avertissement dont vous parlez dit "il peut produire", ne dites pas "il doit produire". Vous avez donc le choix. Soit ajouter une vérification nulle ou non

Donc, si vous êtes sûr que findViewById dans votre code ne sera jamais la cause de NPE, alors n'ajoutez pas la vérification nulle.

0
Ryan