I Know that in Java we use final keyword to variables or something else to make its values not to be changed.
What is the difference in using final as in the example below?
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView campoTexto = (TextView) findViewById(R.id.campoTexto);
Button botaoTexto = (Button) findViewById(R.id.botaoTexto);
Button botaoCor = (Button) findViewById(R.id.botaoCor);
final RelativeLayout fundoTela = (RelativeLayout) findViewById(R.id.fundoTela);
It is java...final key word is always the same either in android or not in android. It depends on what you apply to.
For example
Apply to the variable means it cannot be changed after initialized.
Apply to method means it cannot be overload the method.
Apply to the class and you cannot override that class.
Final only lock the reference. Not the object and method inside the reference.
In Android it's just like the way in Java.
For example, final int a = 5, then a cannot be changed.
Final final TextView campoTexto; then campoTexto cannot be redefined, but the method inside, like setText or others, are allowed to use.
A more comprehensive example is Final Deque<Integer> stack = new ArrayDeque<>(); then stack cannot be redefined, but stack.push, pop and other methods are allowed to use, so the object inside the stack are allowed to change
For variables, the final keyword means it is basically a constant. In this case, as it is an object, its reference cannot be changed. So basically if you try to assign to final TextView campoTexto again, the compiler will throw an error out.
Related
I want to run a class multiple times, lets say I have a class
public class setTextClass {
public void setTextClass (String text){
this.text = text;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textview.setText(text);
}
public void run{
textview.setText(text);
}
}
So, As I see, if I initiate the class doing:
setTextClass hi = new setTextClass("hello");
The code on the onCreate will run right? (this is my first question)
And then, if I run the code:
hi.run()
The code over the run method will be executed and also will pass the text variable that was assigned at the initialization?. This is my second question. I'm learning java, sorry if this is a really basic question
First of all, it's difficult to address question with basic java and Android misconceptions in a Stack Overflow answer. SO is not made for these kind of question, that's why you are getting downvotes. So, that said, I'll try to help you a little bit:
First answer: "The code on the onCreate will run right? (this is my first question)"
No. You are probably mixing up because of onCreate method from Android's Activity class, right? But a constructor is something general for all classes in java, while onCreate is a method specific to some Android complex classes, like Activity or Fragment. It is a method related to the lifecycle of these classes and you should read more about it here.
So, in this simple class that you showed, onCreate will not be called in the constructor (unless you explicitly call it in the constructor). You should assign the text to textView inside your constructor.
Second question: "The code over the run method will be executed and also will pass the text variable that was assigned at the initialization?"
Yes, it will run and use the variable assigned to this.text on the constructor. BUT, you are missing the declaration of this global variable for it to work:
public class setTextClass {
private TextView textView;
private String text; // You have to declare your global variables here
public void setTextClass (TextView textView, String text){ // You should pass your TextView in the constructor and assign it to your global variable, so it's not null when you assign text to it;
this.textView = textView;
this.text = text;
textview.setText(text); // Moved from your onCreate method to the constructor
}
public void run{
textview.setText(text);
}
}
I hope I could make myself clear, but you should study more java and do some basic tutorials to better understand the language and it's concepts, so you can ask more specific questions here. Read here about classes, objects, constructors and more
Your onCreate function will not run when you do the initialization:
setTextClass hi = new setTextClass("hello");
instead what will run as its constructor(which should not have a return type because its return type is the object itself) ie:
public setTextClass (String text){
this.text = text;
}
And as for the second question the text variable, that variable only exist in the scope of the constructor or setTextClass method. So if you wanted to do something like that you would need to create and set a class variable.
It seems like you need to do a lot more learning and go through examples of OOP design and scope. I would check out these resources if i were you:
http://www.learnjavaonline.org/en/Objects
http://www.learnjavaonline.org/en/Functions
I am new to Android programming. I want to know that in this code what does the this in
TextView textView = new TextView(this);
this would point to which class or method? I copied this code from here.
The reason you need this when creating a TextView is because one of the the constructors of TextView (the one that you're calling) takes a Context object as a parameter.
That basically means you must give TextView a Context in order to create it.
Where do you get this context from? Well, an activity is a kind of context (Activity is a subclass of Context)! And you're creating the TextView in an activity class right? So just use this activity as the context!
Got it? Use this activity as the context for the TextView! That's why you put this in there. this refers to the object that the code is currently running on.
Since this refers to an object created from the class, you can't use this in a static method because a the code in a static method does not run on any object.
Another use of this is in constructors:
class MyClass {
private int a, b;
public MyClass(int a, int b) {
this.a = a;
this.b = b;
}
}
Since the compiler can't know which a or b you mean, you must add this to refer the a that's in the class.
this refers to the current object's instance that was invoked or initialized.
See: What does "this" mean?
I'm trying to use the array in my android program.
I did this
public class MainActivity extends Activity {
TextView[ ] answer = { new TextView(this) };
and, I tried to do use answer[0]
but it gives me errors. Is there any problems with me initializing the arrays?
(I want to create, and initialize them at once)
Guys thank you.. figured it out by help!
I did
TextView[] answer;
in Main
and did
TextView[] answer = {new TextView(this)};
in On create
this made me able to use answer in other methods! thank you guyz!
The statement
TextView[] answer = { new TextView(this) };
needs to be in an instance method such as onCreate. If you need to access it outside the method declare it as a class member variable:
public class MainActivity extends Activity {
private TextView[ ] answer;
#Override
public void onCreate(Bundle savedInstanceState) {
...
answer = new TextView[] { new TextView(this) };
}
....
}
It refers to the instance of MainActivity on which onCreate() has been called.
In general, from the Java Language Specification, 15.8.3:
The keyword this may be used only in the body of an instance method, instance initializer or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs.
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (ยง15.12), or to the object being constructed. The type of this is the class C within which the keyword this occurs. At run time, the class of the actual object referred to may be the class C or any subclass of C.
You should try this.
public class MainActivity extends Activity
{
TextView[] answers;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
answers = new TextView[]{new TextView(this)};
}
}
It should be defined as:
TextView[] answer = new TextView[]{new TextView(this)};
I have this in onCreate :
final TextView text1 = (TextView) findViewById(R.id.txtNextAlarm);
And I'm trying to set a text in a method that is in the same class :
public static void NextTxt(){
text1.setText("");
}
But it doesn't recognize the "text1".
The problem is that static methods aren't associated with any particular object, but with the class as a whole. As such, they can only see static fields in your class. Your text1 variable isn't even that, if what you say is true. Instead, it's a local variable that only exists for the length of the onCreate() method. If you know you'll only ever have one instance of your activity (and that's probably not an unreasonable assumption), what you could do is use
private static TextView text1;
at the top of your class (or, basically, anywhere outside of a method). The final modifier doesn't buy you anything. Your choice of whether to make it public or private, but I tend toward private by default (unless there's a reason for something else).
The alternative is to ask yourself why NextTxt() is static; if you make it a normal instance method, then you'd still need to declare text1 in the class, but it wouldn't need to be static. But then you'd need an instance to call it on.
TextView text1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
text1 = (TextView) findViewById(R.id.txtNextAlarm);
}
Do the initialization in the onCreate method.
If the method is static, you cannot access any of the non-static fields of the class. You have to make your textField static or pass it as a parameter.
static TextView text1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyClass.text1 = (TextView) findViewById(R.id.txtNextAlarm);
}
public static void NextTxt(){
MyClass.text1.setText("");
}
Of course you can only have one textField set at the time, because it's a static field of the class. The other options include making a singleton or removing static modifier from your NextTxt method.
If it's true that this line is in your onCreate method
final TextView text1 = (TextView) findViewById(R.id.txtNextAlarm);
then the answer to your question is that text1 is out of scope from within your NextTxt method. You've declared and initialized a variable within one method and you're trying to access it from another one. In order for the NextTxt method to "see" text1, you need to move that member to a place where both methods can access it.
As mentioned in other answers, you're also dealing with the fact that onCreate is an instance method while NextTxt is a static method. You may be tempted to start making everything static in order to "fix" your issues, but this is a dangerous and sloppy path. You don't have control over when Android kills your UI, so text1 could become invalid with no warning. The next time you try to call a method on it, you won't like the results.
Rethink what you're trying to do, sketching it out if necessary and don't just apply quick fixes in Eclipse if you don't understand the error.
text1 is a local variable you have to declare it as an attribute of your class
public final TextView text1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
text1 = (TextView) findViewById(R.id.txtNextAlarm);
}
and in your static method use:
public static void NextTxt(){
text1.setText("");
}
Is it better to give default values to your instance variables in onCreate, onResume or just when declaring them? In code:
When declaring them:
public Class Foo extends Activity{
private String variable1 = "my super var";
private int variable2 = 42;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
OR during onCreate
public class Foo extends Activity{
private String variable1;
private int variable2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
variable1 = "my super var";
variable2 = 42;
}
}
OR during on resume:
public class Foo extends Activity{
private String variable1;
private int variable2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected void onResume() {
super.onResume();
variable1 = "my super var";
variable2 = 42;
}
}
Thank you.
The above answers are good, and it does depend on coding style BUT, as a rule, try to avoid assigning default values other than when the variables are declared. This will help with maintainability. When you come back to your code in 6 months to fix a weird bug, having defaults scattered throughout the code will add to your troubles.
Only use onCreate, onResume etc if there is a purpose in doing so and then, add a meaningful comment e.g.
// re-initialise foobarValue when the app regains focus
// to ensure that the wobbly gong generator starts from the beginning
foobarValue = 1;
Cheers
That all depends on your sense of coding style, and of course the instance variables being assigned. Often, a fair number of my instance variables are views and thus depend on having a valid context - so these I of course put in onCreate(). If I need a variable to be reset every time I leave an activity and return, then it has to be in onResume(). As for inline, I tend to do this when I know that the variable will not change and shouldn't change, and I make them final. The balance between inline constructed variables and onCreate() depends. Some people might like to have all of their assignments in one place, so onCreate() makes sense as a way to capture all assignments in a single location, if you don't care than there's no real performance difference between them, so put the assignment where you want.
I don't think there's a whole lot of difference from doing it as default values or in onCreate if the values are simple. What onCreate is good for is if you need activity-related things like a Context or something from the Intent, etc. Then you have to do it in onCreate.
However, doing this initialization in onCreate vs. onResume makes a huge difference. If you put code in onResume it runs every time you regain focus in the activity (for an exact definition you'll want to read the docs). This means that if you press home and then go back to your app, this code will run again. So it really depends on what behavior you want.