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.
Related
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 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.
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.
This code is throwing a invocationTargetException.
There are a few problems with this code:
It is still entering the if statement even though I specifically told it not too when nothing is input into the EditText.
I am guessing the exception could have occurred because of the parseInt not having anything to parse (Although that shouldn't be a problem).
A cause of this type exception should be not initiating something at the right time, should it not?
if(ageText.getText().toString() != "" || ageText.getText().toString() != null)
{
newCharacterController.characterAge = Integer.parseInt(ageText.getText().toString());
}
A little off topic too, I cant seem to find the tag of any of the containers like a Spinner or EditText, when I look into the mTag value of it when the program is running, will this affect my if(parent.getTag() == "OBJECTIDGIVENBYMYSELF") and stop if from working? Also is there a better way to gain the tag value (.getType() in C#).
An example of the above OBJECTNAMEGIVENBYMYSELF is EditText ***newEditText*** = new EditText(this);.
ageText.getText().toString() != ""
The above code is not a good practice to compare String content, simply because comparison operator such as "==" is used to compare by reference but not value. I think you should use the following code instead
ageText.getText().toString().equals("")
And by the way, check null before this.
I need help with using an if statement in java, here is my code :
if(ans==1)
{
txtans.setText("This is a Prime Number");
}
else
{
txtans.setText("This is NOT a Prime Number");
}
if I remove the setText methods in both statements my program works, but when I leave them there and the program finds ans, then it quits, I'm wondering whats wrong with the statements? or is it not possible to use the setText method within if statements..if so how do I overcome this? What I want to do is print a string to the TextView layout when the ans = 1, any suggestions?
Yes, you can run txtans.setText() in an if statement just as well as you could run it if it wasn't in an if statement. You likely just don't have txtans initialised properly.
A quick google search brought up this as a way to print text to a textview.
Check your code, this erros usually comes when use findViewById() method in a wrong view.
In the activity you use like this findViewById(), maybe you need to call yourView.findViewById();
(If you post your class we can help you with more detailed answear.)
Also note that it is not allowed to call methods from Views from another Thread which created them. But a LogCat output including the Error will enlight us for shure :)
txtans might be NULL and you are trying to access a member of a NULL object.