We have some devs on Android part of our application who actively use prefixing of class member variables with "m*".
What is the origin of "mThis" which is basically:
class SomeClass {
private final SomeClass mThis;
SomeClass() {
mthis = this;
}
}
and this notation in general?
Actually I guess the question is more about the m-prefix, not the goal of having this as your own field.
So regarding the prefix, this is a coding convention used by android team: all member variables (aka fields) are prefixed with "m". That's it, basically. Other android developers might use it because they have browsed through android sources and have deemed it appropriate to use this convention in their own code.
BTW, it's not common in general java programming, I believe common java coding standards usually discourage using any kind of prefixes for anything.
I assume it comes handy when you need to pass a reference to the instance in an inner class, and you don't want to use the "fully qualified" this. i.e SomeClass.this. Nevertheless, it seems redundant to me.
This article suggests it comes from ancient habits peculiar to the Microsoft ecosystem -- however, prefixing members of structs with some shorthand of the struct it is contained in is an old C habit from the days when identifiers, all identifiers (include structure member names), had to be unique in the first eight characters. Prefixing the names with a short-hand version of the name of the containing structure was an easy mechanism to ensure unique names:
struct inode {
int number;
struct device *dev;
}
struct file_descriptor {
int number;
struct inode *i;
}
In this case, number is duplicated, non-unique, and trouble.
Newer versions of C made this a non-issue by placing struct names into their namespaces, but some portion of this habit has carried over: the Linux kernel, for example, is filled with:
struct iattr {
unsigned int ia_valid;
umode_t ia_mode;
uid_t ia_uid;
....
and
struct inode {
/* RCU path lookup touches following: */
umode_t i_mode;
uid_t i_uid;
gid_t i_gid;
const struct inode_operations *i_op;
struct super_block *i_sb;
...
where the leading ia_ and i_ are from the struct iattr and struct inode -- which makes it slightly easier to read chains like this:
if (!IS_ERR(cookie) && path->dentry->d_inode->i_op->put_link)
path->dentry->d_inode->i_op->put_link(path->dentry, nd, cookie);
(Really. fs/namei.c, lines 821 and 822 in my source.)
It avoids accidently using a local variable when you meant to use the member (which the m is short for) variable of the object.
private String name;
private String mName;
public void setName(String name) {
name = name; //wrong, just set the parameter variable to itself
this.name = name; //ok, but has 'this.' which isn't a problem, but some people don't like it
mName = name; //simples
}
m for member variables, s for statics. It's a common naming convention. But like neutrino I don't use it very much. If you use a modern IDE, the syntax color-coding gives you the same information (actually more, because it works whether the original coder followed the naming convention or not).
I use the m prefix to define global variables for the class instance. I don't know why, but when I started and looked over other android code, it was like that.
Related
I have an enum like this:
public enum Type {
VIDEO(10,"video"),
AUDIO(11,"audio");
int code;
String desc;
Type(int code,String desc){
this.code = code;
this.desc = desc;
}
}
But , Enumerations are not recommended in Android,How to do it with typedef, or is there another better way?
You can using #IntDef but still need method to convert code to desc. But take a look article from Google Developer, he said now enum isn't a big deal, not overhead memory and already optimize by R8 read here
#Retention(SOURCE)
#IntDef({VIDEO,AUDIO})
public #interface Type {}
public static final int VIDEO = 10;
public static final int AUDIO = 11;
#Type int type
In your example enum, you don't really need desc value, since you can use name() method (and even toString()), for example
final String desc = Type.VIDEO.name();
you could turn String result to lower/upper case as your convenience.
On the other hand, #IntDef is a way of replacing an integer enum where there's a parameter that should only accept explicit int values. If you have a parameterized enum with multiple hardwired values, like yours VIDEO(10,"video", "etc...") you should consider use the enum.
You can also create an annotation using a custom class and then use it in the same way as someone mentioned in this response Convert parametized Enum to Enumerated Annotation in android
I have never tried R8 yet, as #Công Hải mentioned, and evaluate its performance on enums. You will find multiple articles about how bad are enums for your app, and they most seem quite right. But don't avoid it strictly. I would try to use #IntDef or #StringDef, as much as I could, but it is not always simple. My adivice, you should analyze if you want to lose code readability for avoiding enums, or suffer for the overhead they may cause. You can always try.
Enums are no longer an issue for Android thanks to the replacement of Dalvik as runtime environment by ART. You can find more information about it in this Google IO video from 2018: https://www.youtube.com/watch?v=IrMw7MEgADk&t=849s - If you don't want to watch the whole vid you can fast forward to the minute 14:09.
Plus, thanks to R8, most enums are optimised at compile time too: https://jakewharton.com/r8-optimization-enum-ordinals-and-names/
So go ahead and your Enums :) they make the code more concise, easier to understand and less error-prone than other options.
I used to define a set of related constants like Bundle keys together in an interface like below:
public interface From{
String LOGIN_SCREEN = "LoginSCreen";
String NOTIFICATION = "Notification";
String WIDGET = "widget";
}
This provides me a nicer way to group related constants together and used them by making a static import (not implements). I know Android framework also uses the constants in same way like Toast.LENTH_LONG, View.GONE.
However, I often feel that the Java Enums provide much better and powerful way to represent the constant.
But is there a performence issue in using enums on Android?
With a bit of research I ended up in confusion. From this question
"Avoid Enums Where You Only Need Ints” removed from Android's performance tips? it's clear that Google has removed "Avoid enums" from its performance tips, but from it's official training docs Be aware of memory overhead section it clearly says: "Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android." Is this still holds good? (say in Java versions after 1.6)
One more issue that I observed is to send enums across intents using Bundle I should send them by serializing (i.e putSerializable(), that I think an expensive operation compared to primitive putString() method, eventhough enums provides it for free).
Can someone please clarify which one is the best way to represent the same in Android? Should I strictly avoid using enums on Android?
Use enum when you need its features. Don't avoid it strictly.
Java enum is more powerful, but if you don't need its features, use constants, they occupy less space and they can be primitive itself.
When to use enum:
type checking - you can accept only listed values, and they are not continuous (see below what I call continuous here)
method overloading - every enum constant has its own implementation of a method
public enum UnitConverter{
METERS{
#Override
public double toMiles(final double meters){
return meters * 0.00062137D;
}
#Override
public double toMeters(final double meters){
return meters;
}
},
MILES{
#Override
public double toMiles(final double miles){
return miles;
}
#Override
public double toMeters(final double miles){
return miles / 0.00062137D;
}
};
public abstract double toMiles(double unit);
public abstract double toMeters(double unit);
}
more data - your one constant contains more than one information that cannot be put in one variable
complicated data - your constant need methods to operate on the data
When not to use enum:
you can accept all values of one type, and your constants contain only these most used
you can accept continuous data
public class Month{
public static final int JANUARY = 1;
public static final int FEBRUARY = 2;
public static final int MARCH = 3;
...
public static String getName(final int month){
if(month <= 0 || month > 12){
throw new IllegalArgumentException("Invalid month number: " + month);
}
...
}
}
for names (like in your example)
for everything else that really doesn't need an enum
Enums occupy more space
a single reference to an enum constant occupies 4 bytes
every enum constant occupies space that is a sum of its fields' sizes aligned to 8 bytes + overhead of the object
the enum class itself occupies some space
Constants occupy less space
a constant doesn't have a reference so it's a pure data (even if it's a reference, then enum instance would be a reference to another reference)
constants may be added to an existing class - it's not necessary to add another class
constants may be inlined; it brings extended compile-time features (such as null checking, finding dead code etc.)
If the enums simply have values, you should try to use IntDef/StringDef , as shown here:
https://developer.android.com/studio/write/annotations.html#enum-annotations
Example: instead of :
enum NavigationMode {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}
you use:
#IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
#Retention(RetentionPolicy.SOURCE)
public #interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
and in the function that has it as a parameter/returned value , use:
#NavigationMode
public abstract int getNavigationMode();
public abstract void setNavigationMode(#NavigationMode int mode);
In case the enum is complex, use an enum. It's not that bad.
To compare enums vs constant values, you should read here:
http://hsc.com/Blog/Best-Practices-For-Memory-Optimization-on-Android-1
Their example is of an enum with 2 values. It takes 1112 bytes in dex file compared to 128 bytes when constant integers are used . Makes sense, as enums are real classes, as opposed to how it works on C/C++ .
With Android P, google has no restriction/objection in using enums
The documentation has changed where before it was recommended to be cautious but it doesn't mention it now.
https://developer.android.com/reference/java/lang/Enum
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/en/proguard/manual/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 [...] 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
Should I strictly avoid using enums on Android?
No. "Strictly" means they are so bad, they should not be used at all. Possibly a performance issues might arise in an extreme situation like many many many (thousands or millions of) operations with enums (consecutive on the ui thread). Far more common are the network I/O operations that should strictly happen in a background thread.
The most common usage of enums is probably some kind of type check - whether an object is this or that which is so fast you won't be able to notice a difference between a single comparison of enums and a comparison of integers.
Can someone please clarify which one is the best way to represent the same in Android?
There is no general rule of thumb for this. Use whatever works for you and helps you get your app ready. Optimize later - after you notice there's a bottleneck that slows some aspect of your app.
I like to add, that you can not use #Annotations when you declare a List<> or Map<> where either key or value is of one of your annotation interfaces.
You get the error "Annotations are not allowed here".
enum Values { One, Two, Three }
Map<String, Values> myMap; // This works
// ... but ...
public static final int ONE = 1;
public static final int TWO = 2;
public static final int THREE = 3;
#Retention(RetentionPolicy.SOURCE)
#IntDef({ONE, TWO, THREE})
public #interface Values {}
Map<String, #Values Integer> myMap; // *** ERROR ***
So when you need to pack it into a list/map, use enum, as they can be added, but #annotated int/string groups can not.
Two facts.
1, Enum is one of the most powerful feature in JAVA.
2, Android phone usually has a LOT of memory.
So my answer is NO. I will use Enum in Android.
I am trying to get a basic understanding of how to specify string encryption using the command -encryptstring in the file dexguard-project.txt. For example, I see
-encryptstrings "android.content.pm.PackageInfo",
"packageName",
"versionName",
"versionCode",
............ ,
"java.lang.String",
............
What does it mean?
There's good example of the options in the DexGuard docs {dexgaurd root}/samples/StringEncryption/dexguard-project.txt
Here's the ones I tend to use.
#encrypt a specific string in a class
-encryptstrings class com.example.HelloWorldActivity {
private static final java.lang.String MESSAGE;
}
#encrypt all strings in the class.
-encryptstrings class com.example.HelloWorldActivity
#specify the string itself, i.e any instance of "Hello world!" in your app.
-encryptstrings "Hello world!"
I do not know yet what the code means (in details) but it does not mean that precisely the specified strings should be encrypted. (Here by string I mean any one item in the list following the encryptstring command.) Rather, it means roughly that the specified instance variables in the Android class PackageInfo should be encrypted, also all the instances of the Java class String should be encrypted. I am still looking for a better understanding.
I am looking at opcommon.cpp in Android 4.3 and comparing it to the same file in 4.1.1
In both 4.1.1 and 4.3 the file Object.h defines the structure Instfield as
struct InstField : Field {
int byteOffset;
};
and the structure Field as
struct Field {
ClassObject* clazz; /* class in which the field is declared */
const char* name;
const char* signature; /* e.g. "I", "[C", "Landroid/os/Debug;" */
u4 accessFlags;};
now my question is pretty simple:
given the declaration InstField* ifield;
opcommon has changed from using ifield->field.name in 4.1.1 to using ifield->name in 4.3
to retrieve the name variable.
What is the difference and is either better? If not why would they change it?
I could not google this question because the -> was just ignored an I don't know the word to describe the operator. eg field.name is referencing a variable in a structure and -> is used to dereference pointers and does the same but what's it's name?
Another tiny question on terminology, is the InstField structural definition a wrapper or an extension?
It would have been helpful if you had posted code snippets from 4.1.1 also. ifield->field.name suggests that field itself is a member of the struct InstField and that field is also a struct with a member name (could be any struct, not necessarily of type Field). ifield->name on the other hand suggests that name itself is a member of the struct InstField (by Inheritance) and is not a member of a member. You need to look at the part of 4.1.1 where InstField is defined. It's probably different than this definition which you got from 4.3.
inside of a single activity, when defining components to be used only within that activity, what's the real difference between the following definitions:
Button btnPower = null;
//or
private Button btnPower = null;
//or
public Button btnPower = null;
public void somethingUsingTheButton(){
btnPower = (Button)findViewById(R.id.btnpower_id);
}
are there some "under the hood" conventions that should be thought about (garbage cleanup, memory, etc) that would suggest to always use private over public, if the entity itself is only ever going to be used inside the class it's written in?
Private fields promote encapsulation
It's a generally accepted convention to use private unless you need to expose a field or method to other classes. Getting in this as a habit will save you a lot of pain in the long run.
However, there isn't anything inherently wrong with a public field or method. It causes no difference for garbage collection.
In some cases some types of access will affect performance, but they are probably a bit more advanced than the topic of this question.
One such case has to do with inner classes accessing outer class fields.
class MyOuterClass
{
private String h = "hello";
// because no access modifier is specified here
// the default level of "package" is used
String w = "world";
class MyInnerClass
{
MyInnerClass()
{
// this works and is legal but the compiler creates a hidden method,
// those $access200() methods you sometimes see in a stack trace
System.out.println( h );
// this needs no extra method to access the parent class "w" field
// because "w" is accessible from any class in the package
// this results in cleaner code and improved performance
// but opens the "w" field up to accidental modification
System.out.println( w );
}
}
}
well,
one important point is that defining variables as private is the standard in java programming.
So calling directly variables on objects will at least appear strange for other people that may possibly read your code.
One other thing I'd say is that if you are not alone coding on a project is always a good practice to limit the visibility of the attributes that are key on the class implementation to avoid strange work around that other developers may come up with.
I personally don't know if those modifiers are used to compiling and optimization purpose.
to conclude as I think every experienced java coder I strongly sujest to use this pattern in the definition of attributes.
The scope of visibility has nothing to do with the garbage collector or memory management
You will want to reduce the scope of visibility as much as possible so your code can be easier to maintain.
private and public are both keywords of Java that have the purpose of Object Orientated Design. I suggest you read up about this: http://docs.oracle.com/javase/tutorial/java/concepts/
If you are only going to use those variables (objects) in your activity, then I would suggest you make those variables private.
I hope this helps.
Edit:
I'm not sure if using the private, public or no keyword will optimize you app from a memory point of perspective. As far as I can tell I think it does not and you should use what makes your code most readable, intuitive and maintainable.
If your variable declaration is inside the Activity's scope, it acts normally as a scoped variable normally would.
It is, however, bad programming practice to use variables from one method in another method when they're not parameters.
Example:
Bad:
void Foo()
{
int foo = 5;
System.out.println(Bar());
}
int Bar()
{
return foo + 5;
}
This will actually throw a syntax error because foo is declared outside of scope for Bar()
Good:
int foo;
void Foo()
{
foo = 5;
System.out.println(Bar(foo)); //prints 10
}
int Bar(int foo)
{
return foo + 5;
}