I have the following line of code in onCreateView() method of my Fragment. It warns me that the expression to createPinPresenter.setLoginResult() can be null.
So I ask AS to generate the null check and it does this.
Even after the auto generated code, AS still complains the same expression being null. It obviously cannot be null inside the check.
Am I missing something obvious here or is this a bug?
Edit: I'm using AS version 2.2.3
This is correct, how does AS know if, for example, getParcelable() will return the same value? it is just a syntactic control, not a semantic control.
A function could return, for example, null if the number of times it has been called is odd: in that case the warning is correct.
Think this:
if (getNextValue() != null)
value = getNextValue();
If getNextValue() increments an index, at the end of an array it could return null: the error is pretty obvious, and it's actually what the control tries to prevent in your code.
The only solution is to store the result of getParcelable(KEY_LOGIN_RESULT) in a temporary variable, in that case AS will correctly manage it.
And of course... the fact that this is an autogenerated code, is actually a bug, I think, of the autogeneration, that is less smart than the control.
Related
In a using custom views, I override onDraw(canvas:Canvas?) method many times , but I don't understand why this method get a nullable Canvas , shouldn't a view always have a canvas to draw on when it is time to draw?.
I also asserted it non null and it works , but I don't want to take that risk , may be at some point it gets null.
So first I want to understand in what situations that parameter can be null?
or is it just coming from java to kotlin conversion process and i can safely remove the ?from the parameter?
Thanks
Because the Android API was originally written in Java. And in Java, there are no non-nullable values. Since Kotlin needs to be compatible with that Java API, it needs to be a nullable parameter.
If you ever actually get a null it's a bug in the framework. I've never seen it happen. I think you're safe just letting it throw a NullPointerException if it does because you should never see it.
For the record, even the Android framework doesn't check for null on that parameter- TextView.onDraw will crash if you pass in null.
I have some code and when I run it produces an error, saying:
NoSuchMethod: the method 'XYZ' was called on null
What does that mean and how do I fix it?
Why do I get this error?
Example
As a real world comparison, what just happened is this conversation:
Hey, how much gas is left in the tank of the car?
What are you talking about, we don't have a car.
That is exactly what is happening in your program. You wanted to call a function like _car.getGasLevel(); but there is no car, the variable _car is null.
Obviously, in your program it might not be a car. It could be a list or a string or anything else really.
Technical explanation
You are trying to use a variable that is null. Either you have explicitly set it to null, or you just never set it at all, the default value is null.
Like any variable, it can be passed into other functions. The place where you get the error might not be the source. You will have to follow the leads from the actual null value to where it originally came from, to find what the problem is and what the solution might be.
null can have different meanings: variables not set to another value will be null, but sometimes null values are used by programmers intentionally to signal that there is no value. Databases have nullable fields, JSON has missing values. Missing information may indeed be the information itself. The variable bool userWantsPizzaForDinner; for example might be used for true when the user said yes, false when the user declined and it might still be null when the user has not yet picked something. That's not a mistake, it's intentionally used and needs to be handled accordingly.
How do I fix it?
Find it
Use the stack trace that came with the error message to find out exactly which line the error was on. Then set a breakpoint on that line. When the program hits the breakpoint, inspect all the values of the variables. One of them is null, find out which one.
Fix it
Once you know which variable it is, find out how it ended up being null. Where did it come from? Was the value never set in the first place? Was the value another variable? How did that variable got it's value. It's like a line of breadcrumbs you can follow until you arrive at a point where you find that some variable was never set, or maybe you arrive at a point where you find that a variable was intentionally set to null. If it was unintentional, just fix it. Set it to the value you want it to have. If it was intentional, then you need to handle it further down in the program. Maybe you need another if to do something special for this case. If in doubt, you can ask the person that intentionally set it to null what they wanted to achieve.
simply the variable/function you are trying to access from the class does not exist
someClass.xyz();
above will give the error
NoSuchMethod: the method 'xyz' was called on null
because the class someClass does not exist
The following will work fine
// SomeClass created
// SomeClass has a function xyz
class SomeClass {
SomeClass();
void xyz() {
print('xyz');
}
}
void main() {
// create an instance of the class
final someClass = SomeClass();
// access the xyz function
someClass.xyz();
}
I have some code and when I run it produces an error, saying:
NoSuchMethod: the method 'XYZ' was called on null
What does that mean and how do I fix it?
Why do I get this error?
Example
As a real world comparison, what just happened is this conversation:
Hey, how much gas is left in the tank of the car?
What are you talking about, we don't have a car.
That is exactly what is happening in your program. You wanted to call a function like _car.getGasLevel(); but there is no car, the variable _car is null.
Obviously, in your program it might not be a car. It could be a list or a string or anything else really.
Technical explanation
You are trying to use a variable that is null. Either you have explicitly set it to null, or you just never set it at all, the default value is null.
Like any variable, it can be passed into other functions. The place where you get the error might not be the source. You will have to follow the leads from the actual null value to where it originally came from, to find what the problem is and what the solution might be.
null can have different meanings: variables not set to another value will be null, but sometimes null values are used by programmers intentionally to signal that there is no value. Databases have nullable fields, JSON has missing values. Missing information may indeed be the information itself. The variable bool userWantsPizzaForDinner; for example might be used for true when the user said yes, false when the user declined and it might still be null when the user has not yet picked something. That's not a mistake, it's intentionally used and needs to be handled accordingly.
How do I fix it?
Find it
Use the stack trace that came with the error message to find out exactly which line the error was on. Then set a breakpoint on that line. When the program hits the breakpoint, inspect all the values of the variables. One of them is null, find out which one.
Fix it
Once you know which variable it is, find out how it ended up being null. Where did it come from? Was the value never set in the first place? Was the value another variable? How did that variable got it's value. It's like a line of breadcrumbs you can follow until you arrive at a point where you find that some variable was never set, or maybe you arrive at a point where you find that a variable was intentionally set to null. If it was unintentional, just fix it. Set it to the value you want it to have. If it was intentional, then you need to handle it further down in the program. Maybe you need another if to do something special for this case. If in doubt, you can ask the person that intentionally set it to null what they wanted to achieve.
simply the variable/function you are trying to access from the class does not exist
someClass.xyz();
above will give the error
NoSuchMethod: the method 'xyz' was called on null
because the class someClass does not exist
The following will work fine
// SomeClass created
// SomeClass has a function xyz
class SomeClass {
SomeClass();
void xyz() {
print('xyz');
}
}
void main() {
// create an instance of the class
final someClass = SomeClass();
// access the xyz function
someClass.xyz();
}
Let's say we call a method on a variable fetched through findViewById():
TextView tv = (TextView) findViewById(R.id.text);
tv.setText("Some text");
Android Studio automatically warns us that setText() may produce a NullPointerException if tv turns out to be null. If we however are certain that tv will never be null (unless something really wonky happens which should crash the app anyway), is it really worth encapsulating the method call within an if(tv != null){} statement? What if these two (or more) rows are executed very often? Can we gain any significant performance increase?
I personally don't think there is much point in checking these are null because you will know if they are present in your layout file or not, so I wouldn't bother.
However, I do sometimes use the following to prevent the warnings in Android Studio:
assert tv != null;
I don't know how this affects performance but I imagine it will have almost no difference.
Throwing or creating new exceptions will definitely consume more resources than what you might expect BUT it is always good to handle the exception where necessary rather than let the app crash. IF you are absolutely certain that the textview or whatever UI element ISpresent in the correct XML for your activity and/or the fragment then i don't think that you should use try catches at all..
Yes you can use asserts to avoid warning of Android Studio as mentioned above, and with respect to performance I don't think you will notice any huge performance variation. However, its always good to catch exceptions and log them as it can be really useful while debugging.
Actually, it can be null.
If you have complicated layout, and many ids, it can happen if you type id of other layouts.
This is only a warning. If your layout is simple to remember all ids or you sure it's never null, don't bother this warning.
This warning is helpful when you change an id in layout manually.
EX:
layout 1 has ids : text_view_1, button_1
layout 2 has ids : text_view_1, button_2
Activity 2 use layout 2 and findViewById(text_view_1)
If you change from text_view_1 to text_view_2 (MANUALLY by typing). No error happened, because id text_view_1 is still exits. But NullPointerException will occur when you run application.
To get better programming skills, I read some sources from others.
I ask myself everytime, what the best way of validation is.
Here you will find some seafile code snippets for android. I'm wondering, why nobody will check in line 109, if ActionBar is null.
On other posts here on SO, I found something like this:
TextView Foo = (TextView) findViewById(R.id.FooBar)
In that post it was said, that this can result in a NullPointer or CastException. That's right. Unfortunately, even Google doesn't do this validation in its own reference.
Do you have any idea, how to deal with it? When should I check, if something is Null or not?
In my opinion
TextView Foo = (TextView) findViewById(R.id.FooBar)
is an example in which it's either always null or never null or CastException or no exception. So I'd not check it for null or check for that exception, since it never changes. If it runs once, it will always run ;)
I'd rather concentrate on checking for null whenever the result actually can be null or not null.