What is the proper way to call view's method:
findViewById(R.id.btn_Foo).setVisibility(View.GONE);
vs
Button fooBtn = (Button) findViewById(R.id.btn_Foo);
fooBtn.setVisibility(View.GONE);
As I understand correctly, as a general Java code efficiency rule, one should use variables. But in this case, what if the view method called only once - does it mean that calling setVisibility without defining a variable is more effcient?
does it mean that calling setVisibility without defining a variable is more effcient?
Performance-wise, the efficiency of the two approaches are almost, if not completely, the same, if that's what you mean by "efficient".
If "efficient" means the time it takes to write the code, then of course the first approach is more efficient.
But in this case, what if the view method called only once
As a general rule, when you want to use the foo button later in the code, you want to make it a variable. If you just want to use it once, it's fine to not declare a variable. However, not needing to use an object twice now does not mean you won't need to use it again next month. It is very possible that next month, you found a bug in your code or you want to add a new feature and now you need to use foo button twice. If you haven't declared fooButton as a variable a month ago, you would have to declare it now.
So unless you are 200% sure that foo button will never be used again in the same scope, make it a variable. It is a View after all, and you tend to refer Views very often.
Related
In Android, whenever we want to have a View like a custom Button subclass call out to a consumer that's using it in a layout, the normal pattern that I've seen used is to define a Listener interface, define methods on the interface that are to be implemented, and then have a listener property in the custom View subclass that will call them at appropriate times. This works well enough but sometimes I feel that this can get unwieldy and less direct, at times - especially when I just want a single method and I know there's not going to be a future addition.
I've been switching to Kotlin recently and I've been wondering if it makes sense to simply have a direct function var declared in the View subclass, as Optional with a null default value, something like this:
class SuperAmazingButton: ImageButton{
var customAction: (()->Unit)? = null
}
When we need to call customAction we can do it in a simple one liner like this along with the safe null check:
customAction?.invoke()
What I'd like to know is if there are any downsides to this approach? Will the android Context that is holding on to the View somehow get leaked when the Activity or Fragment gets dismissed? Are there any other problems that can occur? I mean this looks so simple, easy and straightforward without requiring any new files - it's almost too good to be true!
I'm approaching completion of my first true App..
Along my road (in the past couple years) I've seen many examples of code.
One thing is consistent: I always see the use of static context references such as:
getApplicationContext(), this.getActivity(), and many other such references..
But earlier today, after asking how to retrieve Context from a Method within a Receiver,I was told simply "pass it the Context", ex: public void receiverMethodCall(Context context).
My Question is: If it's that simple, why do people frequently make repeated static context references inline within their code, over and over again, instead of simply passing the containing Method a Context to begin with, and referring to it using "context" when needed?
I Hope that I got your question meaning - you got your answer and told to pass on the context as a context typed variable - but do not forget that when you want to call your method and pass it a context, you will have to know what this context is and initialize it.For example, if you want to make a Toast one of the method parameters is context and if you are using a lot of Toasts it would be better to have context reference and use it for every time you want to show a Toast(or use any other method that requires context.)rather than using this.getActivity() orgetApplicationContext().By doing this you can prevent a duplicated code and you won't need to refer to the context in your code a lot of times, now for the question about "why do people frequently make repeated static context references inline within their code".
I can think of one case when it won't be a bad thing to make 2 context reference: let's say that you have 2 methods in the same activity that are using context - if those methods are used once then you can create context reference inside the method and let the garbage collector handle that reference.I do have to say that I agree with you, I think that if its optional just pass context to your method and let it use it, its really simple solution.
In Android/Java, if I have a button, I can add a click listener two ways -
1)
Button button = findViewById(R.id.my_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
-- or --
2)
Button button = findViewById(R.id.my_button);
button.setOnClickListener(this);
I sometimes prefer option #2, mainly because of brevity, but am curious about the performance considerations of essentially passing the entire class/context to the Listener...
Does anyone have any thoughts/experience in regards to this ?
I think both methods are valid
All depends on what you want to do. For example, if you have many buttons on a screen and you choose to use the first option, for each button you'll need a new object to handle the click. In contrast to the second option, with the same object (activity) as a listener, you'll consume fewer resources because it would be creating fewer objects (Java).
On the other hand, remember that the view holds a reference to context.
The latter approach is obviously more efficient: All it does is passing a reference to this, an already existing object, to setOnClickListener, which will then be used to call onClick.
The first approach is slightly less efficient as it creates a new object, an instance of an anonymous inner class. The creation of a new object and the existence of an additional class is the main difference.
You might also produce some overhead using the first approach when dealing with variable transactions between the surrounding class and the anonymous inner class. Most issues, e.g. threading related problems, affect both approaches.
Summing up, there is no real performance difference. If you are going to create a lot of buttons, you should consider sharing a single instance of a View.OnClickListener.
I usually prefer anonymous inner classes (up to a limited size), because it separates the code that actually belongs to the surrounding class from the code related to the listener.
The actual contents of your listener implementation will affect the performance way more than the call to setOnClickListener. From the perspective of setOnClickListener, both calls are equal as they both pass an instance of a class implementing View.OnClickListener, whether reused or created.
This is a question regarding the syntax used in Eclipse SDK while programming some JAVA code for an Android App.
I am an embedded microcontroller engineer that's mainly used to programming in Assembler (a long time ago) and C. I am a newbie when it comes C++ and JAVA and to help me write my code I have been using a mix of the developer.android.com for background info and stackoverflow.com for real world examples and have found them very useful.
So, I have no problem writing code to do what I want to do because I've always done it, but I am finding it very difficult getting my head around the syntax used in writing Android Apps.
For example to access the GPS one of my lines of code read thus:
LocationManager locationManager = (LocationManager)
this.getSystemService(Context.LOCATION_SERVICE);
but can be shortened to this:
LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
I prefer the second version, but why were some examples written like the first example? Both seem to work fine. I've seen other examples that look even more complicated using "Class".
Secondly, is this not a complicated way to do a really simple thing:
Toast.makeText(getBaseContext(),"Hello World",Toast.LENGTH_SHORT).show();
Why not:
Toast("Hello world");
It now takes me four times as long as it use to write code.
The line break after the cast there is just to keep the lines from getting too long.
On this:
Toast.makeText(getBaseContext(),"Hello World",Toast.LENGTH_SHORT).show();
... it would be simple to write it as you say, aexcept that doesn't do the same things. Basically, that line is
Finding the outermost enclosing place to put graphics
Setting the text you want to show, and setting some formatting or some such
and then showing it.
You want to split those up because you don't always write to the outermost world, and you may want to, for example, make several different chunks of text and show90 or hide() them later. (Think an error message and a success message, for example. You like to build them once and then show/hide the ones you don't need.)
Now, if you can define what context you want and never want to mess with the visibillty, you can make a function that does just that.
It is kind of beginner OOP-ish style to put this everywhere. It is implied in your second example, and the second example is the more common style.
Now this one has to do with a bit of engineering. Yes, your second short example could have been implemented (except that Toast is a class, not a function, but a similar thing would work), but it would preclude a lot of important things you may want to do. A Toast may not be all that lightweight of an object; you may want to cache it. That's why you first get an instance with makeText and only then call show on it. The Toast instance will also have a complete lifecycle that you need to control, but won't be able to with your simple example. The instance can probably undergo further configuration, etc. etc. In short, there's a reason for it which is not obvious from a Hello, world piece of code.
Welcome to the world of Android and Java programming. Since you come from an assembly language background, my advice is: Get used to more typing. :)
Regarding the first code fragment: First, the qualifier this. on the call to getSystemService() is redundant; you can just drop it. Secondly, you can eliminate the qualifier on LOCATION_SERVICE by statically importing the name. Add something like this to the imports for the compilation unit:
import static android.content.Context.LOCATION_SERVICE;
or, if you don't mind the namespace pollution:
import static android.content.Context.*;
Regarding the second fragment: for architectural reasons, Toast eventually needs to associate the popup window to some application context. The first argument to the factory method makeToast is what makes this possible. (By the way, you just need getContext(), not getBaseContext(). You could also stash the context in a field.) As far as the third argument to makeText—arguably, a version of the factory method could have been provided that has a default display time, but Android doesn't provide that, so you're stuck with the third argument as well. You can again avoid the qualifier by statically importing LENGTH_SHORT. Finally, the factory method just returns a Toast object. You aren't required to show() it just yet; it could be stashed and shown at a future time. It's good design to separate creating the Toast object from the action of putting it on the screen.
I will try to explain the things in the easiest way and to the best of my ability.
1. ".this" refers to the current object in Java. ".this" specifically points to the current object accessing its own instance variable members of that class.
2. Using "this" is just being more specific.
3. Now in the case of Toast, It requires the "context" parameter to point to the Activity
where it will display the Toast.(ie on which activity)
4. You can use "this" if you are not inside an Anonymous class, or if you are in an Anonymouse class then use "Your_Activity_Name.this" in place of context.
5. getBaseContext, getApplicationContext are like global access to the parts of the Application.
6. I always prefer Your_Activity_Name.this in context place. Context means the Activity, on which the Toast is going to be displayed. And yes there is No Toast(String s) method in activity.
I guess this is a lame question, I can't even make up a proper subject! Here is what I'm trying to do under Android:
public void onCreate(Bundle savedInstance) {
...
AskFilename ask = new AskFilename();
...
}
Here, AskFilename class will present a user interface to let the user enter a filename. However, the ask object will be out of scope once the onCreate() method returns. So this means there will be no reference to ask any more (assuming inside AskFilename class, I did not assign its this pointer to any other variable), and so GC will, sooner or later, "collect" it. When this happens, if the user hasn't OK'ed the dialog box, the code in AskFilename is already unavailable and therefore the system will crash. Is my understanding correct?
(I can't think of a way to experiement with this idea, because I don't know how to make GC do its job. It seems that GC kicks in only when it wants to! Is there a way to make it do its job?)
If the above is correct, then what is the proper way to new a UI-related object? I know I can make evrything inside AskFilename static, or I can make ask a static vairable and assign it to null when it's done. But is there any other way? Or, the idea itself is bad in the first place?
(Does it make any difference if AskFilename is an "inner" class of the Activity? Like MyActivite.AskFilename.)
Thank you in advance.
Firstly, you can just put the declaration AskFilename ask; outside of the method declaration, i.e. as a member of your class. Then you initialise it with ask = new AskFilename(); in your onCreate method.
However, the thing to know is that your constructor probably won't look like that. Every Android UI component contains a callback (a reference) to the thing containing it. You typically do this by passing a Context to the constructor of a UI component- inside an Activity, the context is usually just the Activity itself, so you just use the this keyword. e.g:
TextView tv = new TextView(this);
However you construct your AskFilename dialog, I expect you will need to pass the Context down to its components. So your constructor will probably need to take a Context argument:
ask = new AskFilename(this);
Additionally, your Activity will hold references (implicitly) to all of its UI components, and dialogs it shows with onCreateDialog() So your object won't get picked up by the GC.
It gets these references either when you call setContextView or make the dialog.