Preface
In Android source code, the management of "multi-state" is always represented by hexadecimal numbers, similar to this format:
// protected int mGroupFlags; static final int FLAG_CLIP_CHILDREN = 0x1; private static final int FLAG_CLIP_TO_PADDING = 0x2; static final int FLAG_INVALIDATE_REQUIRED = 0x4; private static final int FLAG_RUN_ANIMATION = 0x8; static final int FLAG_ANIMATION_DONE = 0x10; private static final int FLAG_PADDING_NOT_NULL = 0x20;
So, have you ever wondered why hexadecimal is needed when encountering multi-state management?
Simple status representation
Let’s give a practical example. As a person, we must have many labels, such asHandsome, cute, knowledgeable, witty, lazy, stingy
。
For these tags, we can set different personalities:
//Define entity class data class Person(var tag : String) //Modify the tag val person1 = Person("Carry") //Judgement tag fun isCute():Boolean{ return == "cute" }
When a person has only one label, it is very simple. Just assign values or judge values directly. But what if a person has multiple tags?
It's also very simple, just use collection storage:
val person2 = Person(mutableListOf()) ("Carry") ("cute") ("cute") ("cute")
However, after using the set, the calculation becomes more complicated, becauseremove
andcontains
The methods are all implemented by traversing the collection. From the perspective of time complexity, the time complexity of deleting a certain tag or determining whether a certain tag exists isO(n)
。
Is there any way to make multiple tags use operations as simple as a single tag just now?
Binary operations
Of course there is, otherwise this article will not happen. Before this, let’s review several binary operations.
1. Bitwise and (&)
When the values of both corresponding bits are 1, the result is 1, otherwise it is 0.
For example:0x1 & 0x4
0001 &
0100
=
0000
2. Bitwise or (|)
When both corresponding bit values are 1, the result is 1.
For example:0x1 | 0x4
0001 |
0100
=
0101
3. Negative (~ )
Inverse a number bit by bit.
For example:~ 0x1
0001 ~
=
1110
Well, with these three operations, our state management is enough.
Introduce hexadecimal
Next, let’s complete a complete state management example.
//Set the hexadecimal value corresponding to all states //Cute, corresponding to binary 0001val TAG_CUTE = Ox1 //Handsome, corresponding to binary 0010val TAG_HANDSOME = Ox2 //Learn, corresponding to binary 0100val TAG_LEARNED = Ox4 var personTag = 0
Status increase
If a binary number wants to leave traces of another binary number (traces of the number 1), we can pass or calculate it, so that as long as there is 1 on a certain bit of the second number, the final result will definitely be 1 in the same number of bits.
Therefore, we can complete the function of increasing state through this method:
//Add cutenesspersonTag |= TAG_CUTE 0000 | 0001 = 0001
After this operation, the number on the fourth digit of personTag is 1, whichTAG_CUTE
This marks.
Status removal
According to the above logic, the removal of state actually requires changing the corresponding number of bits from 1 to 0.
AssumptionspersonTag
Now the value becomes a binary number0111
。
If you want to deleteTAG_CUTE
Attribute, you need to change the fourth bit 1 to 0. Then what we can do is to do firstTAG_CUTE
To reverse it means to turn 0001 into 1110. Then withpersonTag
Perform the AND operation, so that the fourth bit will definitely change to 0, while the values above the other bits will not change.
//personTag is binary number 0111personTag &= ~TAG_CUTE 0001 ~ = 1110 & 0111 = 0110
Complete the rightTAG_CUTE
Removal of status.
Status judgment
Similarly, the judgment of whether there is a certain state is actually to determine whether the value is 1 in a certain bit.
So we only need to perform calculations on the state. If the result is 0, it means there is no such state, otherwise it means there is this state.
//personTag is binary number 0111(personTag & TAG_CUTE) != 0 0111 & 0001 = 0001
The result is not 0, so it meanspersonTag
IncludedTAG_CUTE
This state.
Points to note
Careful friends may find that the hexadecimal value we used just now has skippedOx3
Why is this value?
In fact, it is not difficult to find that the so-called management of state through hexadecimal is actually managed through binary, which ultimately is managed through the number of bits where 1 is located in binary.
Therefore, when we assign a state, we need to select a binary value that occupies a single bit, for example 0001 ,0010,0100,1000,10000
etc.
What happens if other values are used? For example, addOx3
TAG.
//Lazy, corresponding to binary 0011val TAG_LAZY = Ox3 //Add cutenesspersonTag |= TAG_CUTE //Add handsomepersonTag |= TAG_HANDSOME
After we added cuteness and handsomeness,personTag
The binary value of0011
。
Then judge it again to see if it contains a lazy state:
//Is there a lazy state?(personTag & TAG_LAZY) != 0 0011 & 0011 = 0011
The result is not 0. Have we added a lazy state? Obviously not. I am not lazy but I say I am lazy. This is a false accusation!
So do you understand the range of state values?
Why hexadecimal?
At this point, the function of managing state through hexadecimal system has been implemented. It is obvious that this method is much easier to manage states. The fundamental principle is to complete the management of state through binary calculations.
Someone is asking again, since the essence is to complete management through binary, it is OK to use decimal to express it, such as the above example:
//Set the decimal value corresponding to all states //Cute, corresponding to binary 0001val TAG_CUTE = 1 //Handsome, corresponding to binary 0010val TAG_HANDSOME = 2 //Learn, corresponding to binary 0100val TAG_LEARNED = 4 var personTag = 0
Isn't this the same as hexadecimal?
Fundamentally speaking, it is indeed the same, but hexadecimal has the benefits of hexadecimal, which involves the reason why hexadecimal is designed.
In a computer, a byte has eight bits and the maximum value is 1111 1111. The corresponding decimal number is 255, and the corresponding hexadecimal is FF.
Therefore, half a byte can be represented by hexadecimal in hexadecimal, and converting it into decimal is an irregular number.
For convenience, hexadecimal is generally used in the code to represent binary because it can perform a more convenient and intuitive conversion with binary.
Summarize
Today I will introduce to you the commonly used method of managing state through hexadecimal conversion to bin in the source code.
This is the article about Android source code using hexadecimal for state management. For more related content on Android hexadecimal status management, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!