Here http://source.android.com/source/code-style.html#follow-field-naming-conventions it is stated that :
Field Names
Non-public, non-static field names start with m.
Static field names start with s.
Other fields start with a lower case letter.
Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
It also states that :
The rules below are not guidelines or recommendations, but strict rules. You may not disregard the rules we list below except as approved on a need-to-use basis.
I don't like the "m" convention before private or package fields in a class. I really find this uninspired... I mean, if we try to apply good designs, the low coupling of the classes implies having few public fields. actually, in my programs I usually have no public fields, even when I need some I use getters and setters...
So, why should I be forced to have almost all my fields in the program with an "m" in front of them? wouldn't be easier to have the few public fields, if there are any, with some "g" in front or something? or just use setters and getters as beans suggest?
this really makes my code harder to read....
Also, following these guidelines, local temp variables used in the methods have no restriction so they could easily be mistaken for public global fields (also without restriction)... this also I find to be wrong, as it is a probable source of mistakes...
I understand to have a way of differentiating from fields, but private/protected member fields are the most used in an application, they shouldn't be less "readable".
What do you think? Should I follow the guidelines?
Those coding guidelines are for the Android Open Source Project which is the core Android Platform. You have to follow these guidelines if you want any of your code to be accepted into the core platform. You can do what ever you want in your own applications.
With regards to the guidelines themselves I think they are very reasonable and similar to many standards used in commercial applications. Generally you want to use getters and setters for public field access and you don't want to have global public variables. Only global public constants are ok.
So the short answer is follow them for the Open Source project, decide to follow them in you app.
In regards to getters\setters, it is actually recommended to not use them in Android.
I found this on the "Designing for Performance" page (section: Avoid Internal Getters/Setters): http://developer.android.com/guide/practices/design/performance.html
Bottom line, they infer that instance field lookups are more efficient than Virtual method calls (due to optimizations in the JIT).
I think I will continue to use getters\setters in my code, but this might be an easy way to improve performance (especially for apps that do a lot of data manipulation).
Related
I know that when comparing constants to enums constants take up less space and can be primitive. I am researching #Intdef annotation in android and can someone tell me if its better storage to use #Intdef vs a enum. Is it recommended now in android to put enum aside and use #intdef moving forward when possible ? can #Intdef do polymorphism, i doubt?
from the android docs regarding memory overhead:
Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.
#Intdef is clearly more efficient, it carries zero weight over just having static final ints, it's all compile time instructions. enums are classes and as mentioned in your link have a foot print. #Intdef gets you the most basic functionality of enums namely value validation and none of the other features of enums such as automatic String conversions.
Much of the android docs is stale, this could very well be one of them. Back in the early days of android every bit counted but now devices are much more capable. Personally I would choose between those two options depending on what's called for by design and not get too caught up with being efficient. Also the syntax for some of these more advanced annotations doesn't make for clean easy to read code, so not a fan there. However if the situation calls for good old static ints the #Intdef will buy you some protection at the expense of visual clutter.
In addition to previous answers, I would add that if you are using Proguard (and you should definitely do it to reduce size and obfuscate your code), then your Enums will be automatically converted to #IntDef wherever it is possible:
https://www.guardsquare.com/manual/configuration/optimizations
class/unboxing/enum
Simplifies enum types to integer constants, whenever possible.
Therefore, if you have some discrete values and some method should allow to take only this values and not others of the same type, then I would use Enum, because Proguard will make this manual work of optimizing code for me.
And here is a good post about using enums from Jake Wharton, take a look at it.
As a library developer, I recognize these small optimizations that should be done as we want to have as little impact on the consuming app's size, memory, and performance as possible. But it's important to realize that throwing away an Iterator allocation vs. an indexed loop, using a HashMap vs. a binary-searched collection like SparseArray, and putting an enum in your public API vs. integer values where appropriate is perfectly fine. Knowing the difference to make informed decisions is what's important and the video nearly nails that except for this one stupid stat.
Even a private member/function of my class can be accessed by reflection by using setAccessible(true). Is there a way to prevent this kind of access from outside code?
I read something, here on stack-overflow, that I can use SecurityManager for prevention of reflection in applets(not sure how it works, though), but is there a similar mechanism for Android as well? Maybe an annotation or clever-programming?
Taking a step back, what you're observing is a difference in security philosophy, between the Java execution model as originally embodied in JVMs at Sun and the execution model of Android.
The original Java VM design was intended for a system wherein multiple, mutually-suspicious applications (or "applets" in the Java parlance) would simultaneously inhabit a single address space, running in a single VM. Because the designers didn't want one app to be able to mess with another, they went through great pains to define an intra-VM security model that would disallow things such as one object touching the private fields of another object of a different class.
That said, the Java library ended up having various "escape hatches" out of the security model. One of those is setAccessible() on reflection objects, as you note.
Android's model is different: Android uses processes as the security boundary and unit of application isolation, instead of trying to insinuate it into the process as was done with traditional JVMs. This renders moot the entirety of the Java security model, except in that it helps an application "save it from itself." That is, it's good design to not have an object poke into another object's private parts, and the default Java security model provides just that.
Leaving aside the question of people modifying your code, with Android, as an application author, you control all the code that ends up running inside the process of your app. If you choose to include code that calls setAccessible() that's your business. You might be shooting yourself in the foot, but you certainly won't be shooting any other apps' feet, since the Android security model, running as it as at the layer of processes, inherently doesn't let that happen. Likewise, using native code will totally break you out of the Java object model, which allows for the possibility of things going totally higgledy-piggledy in the process but also allows you to express some things in a more productive manner than you could in Java. It's a trade-off, but it's a per-application-developer tradeoff and not one that particularly impacts anything else that's happening on your phone / device.
I know this doesn't directly answer your question, but I hope it provided some useful context.
Is there a way to prevent this kind of access from outside code?
Not really.
is there a similar mechanism for Android as well?
Even if there is (and I am not aware that such a thing exists), anyone can remove it, by decompiling your code (assuming they do not have your source already), getting rid of the protection, and recompiling the code.
Bear in mind that ProGuard, when used properly, will obfuscate your private classes and methods for your production APK builds. That, plus a lack of documentation, will make it tedious for anyone to gain access to those private classes and methods.
I don't believe that you can ever really 100% protect from users using reflection on your project with malicious intent. You can make it more difficult for users to do it by doing things like obfuscating your code, but it is still possible to reflect on the obfuscated code.
I don't believe SecurityManager can be used for the purpose that you are suggesting, though I could be wrong.
Amazing discovery of the day: JNI on Android lets you access object fields that you're not supposed to, according to Java rules.
Is this capability to bypass access restrictions documented anywhere? Is this an official JNI behavior or specific to the Android flavor of JNI? Is this an undefined behavior? Will the OOP police come for me any moment now?
I understand that relying on unpublished object fields is inherently dangerous and may break anytime; that's not the question here.
UPDATE: looks like applications that target API28 no longer have this capability.
The problem has been described and even addressed in an article, or rather proposal published back in 2006.
Note that Javs defines SecurityManager class, but it considers all JNI calls as security breach and thus your question is a non-issue from their standpoint, like asking "why can I get elevation to Administrator when I only install some driver/service?".
But on Android, things are even more explicit. The official documentation describes this class with the following preface:
Legacy security code; do not use.
Security managers do not provide a secure environment for executing untrusted code. Untrusted code cannot be safely isolated within the Dalvik VM.
(the emphasis is theirs)
If you are looking for stronger words that guarantee that access to native fields and methods from JNI will not go away in a next version of Android, good luck to you.
On the other hand, the chances are higher that some future version of Android will change the names or signatures of some private fields and methods. Moreover, they can change the implementation such that the filed remains, but must be used differently.
Finally note, that all these considerations apply not only to private or package private methods, but also to public methods and fields that did not make it into the official documentation!
Amazing discovery of the day: JNI on Android lets you access object fields that you're not supposed to, according to Java rules.
The abbreviation JNI does not appear anywhere in the question and answers that you linked to, except as a dynamically-generated link to this very question.
Is this documented anywhere?
Any decent book on Java development should cover public, private, etc.
Is this an official JNI behavior or Android-specific?
Neither.
What is Android-specific is compile-time steps to make it difficult for you to add code in some android, java, and javax packages.
Is this an undefined behavior?
That depends on what underlying noun or concept you are tying to tying to the pronoun "this".
If "this" is "accessing private, etc. stuff", then the behavior is not undefined.
If "this" is "accessing something specific private, etc. in the Android framework", that is undefined. There are many, many versions of Android around, and many, many versions of framework classes. Their internal implementations are not identical. Anything not exposed via the Android SDK is eligible for change by Google, device manufacturers, ROM mod maintainers, etc.
Effective Java (Joshua Bloch) Item 17 says :
"Design and Document or inheritance or else prohibit it"
However, just a cursory glance through the Android APIs reveals that most of the API classes are non-final; which is OK if they are also documented for inheritance (View of Activity, for example). But there are also several non-final classes, but the documentation makes no mention about the inheritability of these classes. Just some arbitrary examples to illustrate my point:
The classes representing the System Services (WifiManager, NotificationManager ...)
Utility classes like UriMatcher.
Some hardware-specific classes like Camera.
Openness and extensibility being the philosophy of Android, is the convention reversed here? Meaning, could one assume that all of the Android API classes are designed to be inherited (whether explicitly documented or otherwise); unless declared final?
Just my €0,02: Clean OO design by the book is one thing, making things work for all possible use cases in practice is another. The principles of clean OO design sometimes are somewhat of academic nature. - And maybe a little bit of black and white.
Think for instance about who uses the Android API provided by google: It's not only app developers but also device manufacturers who need to specialize general APIs for their devices.
So, for me, SW design is neither black nor white in most cases; the shades of grey are important.
And finally: In practice I have seldom (read: never) seen problems caused by "carelessly" omitted final keywords (on classes), while unreflected overuse of final (often caused by thoughts like "my code is sooo [great | ugly], no one will actually ever want to modify it through inheritance") can be quite a pain.
"I know that I know nothing" seems to fit here: It is presumptuous to claim that one knows all the crazy, ingenious, creative, smart,... ideas of others for how one's code may be used in the future beforehand.
The Android developers went to great lengths to ensure that extensibility, while not recommended in many cases, is possible. The motivation behind this appears to be related to testing environments.
For instance, it would be much more difficult to create a faux WifiManager for the purposes of creating unit tests if it were finalized. Without the finalization, it is trivial to subclass the WifiManager (e.g. to mimic "unexpected" wifi disconnection during operation) and return an instance of this subclass from a customized testing Context.
So while you will probably never find a reason to implement a subclass of the these classes in an application that you ship to the end users, the flexibility is there to allow you to extend them if it is necessary for one reason or another.
In the case of utility classes, the answer is simply that the utility of the class is not diminished by allowing the developer to subclass; in many cases, a developer can achieve more understandable code reuse by inheritance than by aggregation and delegation.
I defined static variables in Activities in order to pass complex data between Activities.
Many people suggest not to use any static variables in Android. Some people suggest to store global data in a custom android.app.Application. I don't think there is any difference between static variable and custom Application.
I'd like to know your thoughts on static variables. Any suggestions?
Thanks.
Dear god don't do that. If you need to pass objects between activities, use a service.
Static variables are per definition global variables as they are scoped to a class instead of to an instance.
Depending on your design , it might perhaps it's better/cleaner/easier to have these global variables centralized instead of scattered over a plethora of classes.
Furthermore, in traditional software engineering, global variables are considered a bad thing, and that is correct, but when programming in a platform as Android where resources are scarce and optimal use of the resources to boost performance are of most importance so you should be developing with a totally different mindset.
Global variables don't have to be too bad in such a case.
Please note that the Android platform also provides a Service interface which could fit your need for sharing variables between Activities.