Following snippet produces a lint warning in Android Studio.
Bundle extras = getIntent().getExtras();
if (extras != null && extras.getString(REDIRECT_KEY) != null) {
switch (extras.getString(REDIRECT_KEY)) { ...
extras.getString(REDIRECT_KEY)
produces the warning
Dereference of 'extras.getString(REDIRECT_KEY)' may produce 'java.lang.NullPointerException'
But I don't see any scenario where this could happen. Is it a bug in lint checks, that it simply does not recognize my null-checks in the if before? Or do I miss something?
EDIT: changing the code to following, did remove the warning
if(getIntent() != null && getIntent().getStringExtra(REDIRECT_KEY) != null){
switch (getIntent().getStringExtra(REDIRECT_KEY)){
...
}
}
BUT this is only gone because of the way, this lint check works (at least I guess). If I show more infos to this check, it says at one point
Variables, method parameters and return values marked as @Nullable or @NotNull are treated as nullable (or not-null, respectively) and used during the analysis to check nullability contracts
Looking at the source code of Bundle and of Intent shows:
/**
* Retrieve extended data from the intent.
*
* @param name The name of the desired item.
*
* @return the value of an item that previously added with putExtra()
* or null if no String value was found.
*
* @see #putExtra(String, String)
*/
public String getStringExtra(String name) {
return mExtras == null ? null : mExtras.getString(name);
}
And BaseBundle
/**
* Returns the value associated with the given key, or null if
* no mapping of the desired type exists for the given key or a null
* value is explicitly associated with the key.
*
* @param key a String, or null
* @return a String value, or null
*/
@Nullable
public String getString(@Nullable String key) {
unparcel();
final Object o = mMap.get(key);
try {
return (String) o;
} catch (ClassCastException e) {
typeWarning(key, o, "String", e);
return null;
}
}
As you can see, BaseBundle sets its return values to @Nullable, while Intent doesn't. So using getStringExtra
only removes the symoptoms, not the cause. I still guess this is caused by an insufficient lint check, instead of wrong coding on my side. Or does anyone still see a scenario, where a Null pointer can be thrown?