Android Development Note: Use Enum (enum type) to replace integer set of application detailed _android

Source: Internet
Author: User
Tags constant definition
In the Android API you can find a lot of places that use integer sets as parameters, and look at the examples first.
LinearLayout is a familiar UI basic element that has a directional attribute in it, which can be set in the following ways:
Copy Code code as follows:

linearlayout.setorientation (int);

When used, this is usually the case:
Copy Code code as follows:

Linearlayout.setorientation (linearlayout.horizontal);
Linearlayout.setorientation (linearlayout.vertical);

But you can also use this:
Copy Code code as follows:

Linearlayout.setorientation (0); Linearlayout.horizontal = 0
Linearlayout.setorientation (1); Linearlayout.vertical = 0x01

You can even do this:
Copy Code code as follows:

Linearlayout.setorientation (Integer.max_value);
Linearlayout.setorientation (Integer.min_value);
Linearlayout.setorientation (2012);

Because the method setorientation receives a parameter that is an integer, you can pass any valid integer---at least this will not have any problems at compile time. It can only cause problems at run time, but as you know, developers are only concerned about whether the program compiles successfully, and as far as the runtime is concerned, that's what users care about, because developers don't necessarily use the programs they've developed.

In addition to this example, this API can be seen everywhere in the Android API, such as setting view visibility, setting WiFi status, and so on. are defined as Integer sets, and then as arguments with integers, and you want developers to pass constants defined in an integer set as arguments. But as you know, not everyone is so disciplined, if everyone can abide by the rules, the world is really harmonious, the egg pull far.
Because developers usually only focus on compiling, if you can apply this rule to compile, it will greatly reduce the likelihood of errors. Interested friends can go to try, give these methods to receive integer parameters to pass some "normal" values, such as 2012,integer.max_value,integer.min_value and so on, see what will happen.
In addition, if the developer passes an integer value that is consistent with the constant definition, although the compilation is not wrong, the readability of the code can be greatly reduced, such as:
Copy Code code as follows:

Linearlayout.setorientation (0);
Linearlayout.setorientation (1);

There's nothing wrong with that, but the reader and the maintainer of the code usually have egg aches.
Of course, Android itself is protected, and if you pass an illegal parameter to the API, it will not have any other effect, but the settings won't work, but the API will use the default value, because for each built-in parameter, there is a default value. The default value, such as LinearLayout orientation, is linearlayout.horizontal, so if you pass an illegal value to setorientation (), the linearlayout remains horizontally aligned, with no other effect. There is an experiment on the orientation of linearlayout in the back.
Also, if you set these properties in the layout XML file, there are no problems, such as:
Copy Code code as follows:

<linearlayout
android:orientation= "Vertical"
android:gravity= "Center" >

Because the XML layout will be processed at compile time, if there are illegal values, there will be compile errors. I think that's one reason Android specifically encourages developers to use XML to make all the layouts. instance, three have no set point to the linear layout, the default is horizontal placement, set a few outrageous values in the code, found that they are still horizontal, that is, set outrageous values do not error, but also does not work: the results of the operation are as follows:


The code is as follows:

Copy Code code as follows:

<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
android:orientation= "Vertical"
Android:layout_width= "Fill_parent"
android:layout_height= "Fill_parent"
android:gravity= "Center"
>
<linearlayout
Android:id= "@+id/linearlayout_test_1"
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content" >

<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ff00ff00"
Android:background= "#aa331155"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Microsoft"
/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ffff0000"
Android:background= "#aa117711"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Apple"
/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ff0000ff"
Android:background= "#aa774411"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Google"
/>
</LinearLayout>
<linearlayout
Android:id= "@+id/linearlayout_test_2"
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content" >

<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ff00ff00"
Android:background= "#aa331155"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Microsoft"
/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ffff0000"
Android:background= "#aa117711"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Apple"
/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ff0000ff"
Android:background= "#aa774411"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Google"
/>
</LinearLayout>
<linearlayout
Android:id= "@+id/linearlayout_test_3"
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content" >

<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ff00ff00"
Android:background= "#aa331155"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Microsoft"
/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ffff0000"
Android:background= "#aa117711"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Apple"
/>
<textview
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ff0000ff"
Android:background= "#aa774411"
android:layout_weight= "1"
Android:textsize= "18SP"
android:text= "Google"
/>
</LinearLayout>
</LinearLayout>

And:
Copy Code code as follows:

Package com.android.explorer;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.widget.LinearLayout;
public class Linearlayouttest extends activity {
@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (r.layout.linearlayout_test);
LinearLayout one = (linearlayout) Findviewbyid (r.id.linearlayout_test_1);
One.setorientation (2012);
LinearLayout two = (linearlayout) Findviewbyid (r.id.linearlayout_test_2);
Two.setorientation (Integer.max_value);
LinearLayout three = (linearlayout) Findviewbyid (r.id.linearlayout_test_3);
Three.setorientation (Integer.min_value);
}
}

using an enum instead of an integer set
In fact, it is very simple to use an enum (enum) can be very convenient to solve this problem, use is not more than the definition of a set of tedious, the same readable. Another advantage is that it is better encapsulated, and most importantly, it is checked at compile time. Because Java is a strong type, that is, at compile time, the compiler checks all stereotype types and parameter types, and if the type is incorrect and does not have a forced transition, a compilation error is reported, except for the automatic transitions supported by the compiler. For example, a need for int, and the pass parameter is long, although all the same, no overflow, but there will be compilation errors.
So, if LinearLayout uses an enum, it's like this:
Copy Code code as follows:

public class LinearLayout extends ViewGroup {
private orientation morientation;

public enum Orientation {
Horizontal, VERTICAL
};

public void setorientation (orientation dir) {
Morientation = dir;
}
}

Then use this:
Copy Code code as follows:

Import Android.widget.LinearLayout;
Linearlayout.setorientation (orientation.horizontal);
Linearlayout.setorientation (orientation.vertical);

The developer would not use the wrong one, because first of all, it sees that the parameter required by the setorientation is a orientation enumeration type that naturally transmits the type defined in orientation, and if other values, such as 0 or 1, are passed, The compiler will not agree.

Sadly, almost all of Android's APIs are defined as integer sets, so it's time to remind yourself and everyone in the group that you must pass the constants in the defined integer set.
So what we can do, in addition to the constants to be defined in the integer set, is for those APIs defined in integer sets. More importantly, when you define an interface, try to use an enum instead of an integer set.
And one thing to be aware of is that for some weak-type languages, which means that the type does not have to be specifically examined at compile time, such as c++,c, it is not necessarily safe to use an enum, because the constants in the enum are exactly the same as the integer constants for C + + and C, and the compiler is not even clear. So, for this kind of language, can only hope that the developer.
PostScript:
After writing this, it reminds me of other questions related to parameter definitions, such as Boolean parameters that are not a good design, because it is difficult for the user to pass true or false, especially if the method name does not reflect the Boolean parameters and the document is not clear enough. If only one parameter is OK, it can be known by the method name and common sense, for example:
Copy Code code as follows:

Button.setenabled (TRUE); Enable the button
Button.setenabled (FALSE); Disable the button

However, in some cases, when the name of the method does not reflect the role of the Boolean parameter, or more than one parameter, and the main purpose of the method does not reflect the role of Boolean parameters, it is not clear, such as:
Copy Code code as follows:

Com/android/mms/data/contactlist.java
Public string[] Getnumbers (Boolean);

Can you guess that this boolean variable is a decision to make a special deal for a contact person for MMS? Do you quickly know whether to pass true or FALSE when using this API? When you read these statements:
Copy Code code as follows:

string[] MMS = Getnumbers (TRUE);
string[] SMS = Getnumbers (FALSE);

Can you tell the meaning and effect of true and false? At least when I see such a code, if I do not track its implementation, can not guess.
But the real problem is that APIs often need to be made or not made by the caller. A feasible approach is to encapsulate and hide by means of:
Copy Code code as follows:

Button.setenabled (TRUE); Enable the button
Button.setenabled (FALSE); Disable the button

Can be changed to:
Copy Code code as follows:

Button.enable ();
Button.disable ();

This is a simple situation, for slightly more complex cases, such as the latter example, you can add another interface, rather than overloading the method, but the internal implementation, may still need to overload, but this reduces the problem, at least for the user is hidden:
Copy Code code as follows:

Com/android/mms/data/contactlist.java
Public string[] Getnumbersforsms ();
Public string[] Getnumbersformms ();

In this way, the external is a good package. An internal implementation might still require a private method similar to this:
Copy Code code as follows:

Com/android/mms/data/contactlist.java
Public string[] Getnumbersforsms () {
return Getnumbers (FALSE);
}
Public string[] Getnumbersformms () {
Return Getnumbers (TRUE);
}
Private string[] Getnumbers (Boolean) {
Implementation
}

But at least reduce the problem, you can add a note to explain. There is no need to cause the user to guess the usage and meaning of the method.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.