Why doesn't Android use more enums? - android

I've started to really like using C# and Java enums in my code for several reasons:
They are much more type-safe than integers, strings, or sets of boolean flags.
They lead to more readable code.
It's more difficult to set an enum to an invalid value than an int or string.
They make it easy to discover the allowed values for a variable or parameter.
Everything I've read indicates that they perform just as well as integers in C# and most JVMs.
However, the Android framework has numerous cases where flags of various types need to be passed around, but none of them seem to use enums. A couple of examples where I would think their use would be beneficial are Toast.LENGTH_SHORT / Toast.LENGTH_LONG and View.GONE, View.VISIBLE, etc.
Why is this? Do enums perform worse than simple integer values in Dalvik? Is there some other drawback I'm not aware of?

This answer is out of date as of March 2011.
Enums can be used on Froyo and up - according to this answer (Why was “Avoid Enums Where You Only Need Ints” removed from Android's performance tips?) from a member of the Android VM team (and his blog).
Previous Answer:
The official Android team recommendation is to avoid enums whenever you can avoid it:
Enums are very convenient, but
unfortunately can be painful when size
and speed matter. For example, this:
public enum Shrubbery { GROUND, CRAWLING, HANGING }
adds 740 bytes to
your .dex file compared to the
equivalent class with three public
static final ints. On first use, the
class initializer invokes the
method on objects representing each of
the enumerated values. Each object
gets its own static field, and the
full set is stored in an array (a
static field called "$VALUES"). That's
a lot of code and data, just for three
integers. Additionally, this:
Shrubbery shrub = Shrubbery.GROUND;
causes a static field lookup. If
"GROUND" were a static final int, the
compiler would treat it as a known
constant and inline it.
Source: Avoid Enums Where You Only Need Ints

Integers are smaller, and require less overhead, something that still matters on mobile devices.

A colleague of mine performed a small test regarding this situation. He auto generated a
class and an enum with the same amount of "enums". I believe he generated 30000 entries.
The results were:
.class for the class was roughly 1200KB
.class for the enum was roughly 800KB
Hope this helps someone.

Related

Is there a way to check for unnecessary #SuppressWarnings annotations?

I've recently begun using annotions to help reduce my lint warning count to filter out valid use-cases of warnings/errors.
As an example, let's assume I am 100% correct in having a variable that is never assigned a value (it's being done via GSON serialization but never x = 2 type assignment). Lint reports this as unused variable. I can add the #SuppressWarnings("unused") annotation and lint skips this.
Sometime in the future, would I be able to do an assignment to the x variable, and then have lint notify me that the #SuppressWarnings("unused") flag is no longer necessary? If not, I'd potentially have unneeded code in my application which I would like to avoid.
Any thoughts?

why Google calls variables with the prefix "m"?

why Google calls variables with the prefix "m" for example:
private int mSectionResourceId;
private int mTextResourceId;
I see it in all examples. But i not understand why they do it?
And now i have some example where it practic very good. If a called variabels without prefix i need write
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
this.sectionResourceId = sectionResourceId;
this.textResourceId = textResourceId;
but if i use prefix i can write
public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
RecyclerView.Adapter baseAdapter) {
mSectionResourceId = sectionResourceId;
mTextResourceId = textResourceId;
I think it more readable. Who can explain to me the pros and cons of a prefix?
The variables starting with m are telling you they are variables in the scope of your class. Member of the class.
Link to Android Code Style Guide
The m just stands for 'Member'. It is simply declared that your Variable is a Class-Member.
It is more readable Code, because you know where Class Members got declared, so you can find it pretty fast. You don't need to write this, even if you don't prefix your Variables with an m.
In your Example, this only makes it more readable when there is no prefix-m. Another developer knows that it is a instance variable (member variable) and so declared on top or bottom of the class.
It is a prefix for class member variables. It's just a naming convention.
Mostly sure, taken from Hungarian Notation where similar prefix: m_ stands for exactly the same).
Referring to pros & cons:
Pros:
it allows to type fewer chars during programming,
programmers that are used to use Hungarian Notation may found it easier to follow the code.
Cons:
as the code changes very often, it is easy to forget about changing prefixes every time, when variable changes it's purpose (especially during prototyping),
it makes the code starts to smell bad,
Generally, it is some kind of reinventing the wheel. Java has this keyword that should be more than enough for accessing proper variable. If it's not, the code requires refactoring, maybe because of naming glitches or using too wide variable scopes.
Personally, I do not recommend to use Hungarian Notation (even the part of Android Code Style). We have great IDEs that increases the readability of the code.
There is an exception. The code, where Hungarian Notation (or more general, specific code style) was already been used. It is a matter of consistency.
The m is just a member variable. A class member if you will. Useable with constructors like WebView M WebView then later on you would use something like mWebView.loadurl("example.com"); it's just a placeholder for the variable you created. You don't have to add the member class variable as an m but it's more organized if you do

Android Spinner - System view VS User view

I have been creating Spinner controls (Combo boxes/Drop downs) in one of my apps, and was surprised to find out how difficult it was to achieve all of the following features:
User facing Strings are externalized, taking advantage of strings.xml internationalisation (I18N) feature of Android.
Spinner selections operate using a System view, which facilitates not having to work with or map Strings to meaningful values (yuck).
User view to System view mapping should be easy, automated and minimal (i.e not hand rolled for every component).
Others have attempted solutions to this, but universally as far as I could see they suffer from one or many of the following problems:
UI code is creeping into their enum class which doesn’t belong there (messy), nearly all existing solutions suffered from this.
Hardcoded User facing Strings in their enum classes. Because these are not externalized you cannot do I18N using the stock Android features.
Authors typically make the Fragment or Activity an OnItemSelectedListener which perpetuates a common problem of inheritance for convenience, where composition is more appropriate.
I have developed my own solution which does this: http://www.androidanalyse.com/android-spinner-externalize-user-strings-mapped-to-system-enum/
My question is, have I missed something? This seems like something that should not have been this hard (which makes me feel like I'm possibly reinventing the wheel).
Below is some example code showing my solution in-use (which is available Apache 2 license from the link above).
String none = getString(R.string.none);
String light = getString(R.string.light);
String medium = getString(R.string.medium);
String strong = getString(R.string.strong);
SpinnerUtil.createNewSpinner(view, R.id.wind, Arrays.asList(none, light, medium, strong), WindLevel.values(),
new SpinnerItemSelectedListener<WindLevel>() {
public void onItemSelected(Spinner item, WindLevel value) {
// Take whatever action you wish to here.
}});
I would just use ArrayAdapter<WindLevel>. Yes, you created a custom typed listener, but the regular event listener gets the position and can call getItem() on the ArrayAdapter<WindLevel> to get a WindLevel properly typed.
IMHO, the vast majority of Spinner widgets will be populated with material read in from a database, the Internet, or some other dynamic data source, rather than populated by some sort of enum with display values coming from static strings that can be internationalized ahead of time.
This is not to say that your code is useless: if you find it useful, then it was worth writing. And I am sure that there are apps out there that contain your targeted pattern (i.e., a Spinner backed by an enum or equivalent where the display values are known in advance and can be internationalized) who might find your solution useful as well. Every developer who writes enough code cooks up these sorts of helper classes and the like that help map an OS or framework model into something that better fits the developer's own mental model. So long as you are not perceiving any performance issues, it's all good.
Also, note that OnItemSelectedListener is an interface; implementing that interface on an existing class is not inheritance.
I believe the reason nobody answered you is :
What problem are you trying to solve ? Spinners existed prior to your well designed attempt.
Why reinvent them in exactly the same way they exist in Android ?
http://developer.android.com/guide/topics/ui/controls/spinner.html
It is a beautiful wheel indeed you designed, but still, it is just a wheel :)
UPDATE :
I think I begin to understand what you did. This is interesting. I'm not sure why you did not go to the pattern implemented by the ListPreference with its entries and entryvalues.
In fact, I'm not sure I understand why the Android team did not go that route either.
In any case, it is worth proposing your idea to the Android framework. It is after all open source.

What is the best practices in Android, create new string object (static final) or only use the string.xml file (and call many getters)?

In Android there is an conflict about how to get the best performance (like less Garbage Collector).
First, In Android best practices it recommends avoid getters and setters and also avoid creating short lived objects (like: private static final String name = "my name"). Then, what should i do with all strings that I have in my code? Should I set all of them them in the string.xml file and then get it using "this.getString(R.string.myString)" or its still good for permformance keep using "static final String name = "my name" ???
Due to the big amount of strings in my app, if I use only strings from string.xml it would be too many of "getString"s in all code, isn't that bad?
There is a slight performance overhead in calling getString() but no extra memory overhead. And using string.xml will make managing your strings a lot easier. It also makes it much easier to localize these values if you ever choose to do so in the future.
In addition, the values in your resource files will be compiled into final static Strings so it works out similar in the end.

Optimization: Accessing fields vs. methods

I know rule #1 of optimization is: don't do it! But I figured this was an easy question, and if I start using the faster method now I can save a lot of cpu time when I'm finished.
I'm making an RPG, and let's say this is part of a custom class:
public class Baddie{
int health;
int magic;
public Baddie(int health, int magic){
this.health = health;
this.magic = magic;
}
public int getHealth(){
return health;
}
Now, the answer to my question may be "there's no difference" and that's fine with me.. I just want to know. Is it quicker to get the Baddie's health using field access:
//Somewhere in the main thread, I get an instance of Baddie..
Baddie b = getScaryBadGuy();
int baddieHealth = b.health;
Or is it quicker to use a return method?
int baddieHealth = b.getHealth();
Copied and pasted from Designing for Performance:
Avoid Internal Getters/Setters
In native languages like C++ it's
common practice to use getters (e.g. i
= getCount()) instead of accessing the field directly (i = mCount). This is
an excellent habit for C++, because
the compiler can usually inline the
access, and if you need to restrict or
debug field access you can add the
code at any time.
On Android, this is a bad idea.
Virtual method calls are expensive,
much more so than instance field
lookups. It's reasonable to follow
common object-oriented programming
practices and have getters and setters
in the public interface, but within a
class you should always access fields
directly.
Without a JIT, direct field access is
about 3x faster than invoking a
trivial getter. With the JIT (where
direct field access is as cheap as
accessing a local), direct field
access is about 7x faster than
invoking a trivial getter. This is
true in Froyo, but will improve in the
future when the JIT inlines getter
methods.
Performance is always relative. It's usually better to think in terms of percentages or factors. If something takes a microsecond, maybe that's a lot, and maybe it's nothing. It depends on how many times per second you need to do it. That's the main reason premature optimization is frowned upon, it is done without knowing if there is a problem.
The compiler will optimize if it can. This is a perfect example of premature optimization. use whatever makes sense in your code. Don't worry about "saving cycles". The 2-3 cycles this may or may not save is outweighed by the millions of cycles it takes for any other operation.
IMO it's more a design question than optimization question. I would suggest not writing/generating any getter or setter until you actually need them to be accessed from outside of your class. This tends to keep coupling as low as possible.
Alternatively making those getters/setters private by default would have the same result but it's more code for no real benefit.

Categories

Resources