Today we opened the Android system article, in fact, have always wanted to get, but has not been too much in-depth understanding, and recently took this piece out of a good look, so want to comb a bit, to see the android in this piece of knowledge, First of all, let's take a look at this: the concept of smart pointers in Android, why first look at the knowledge of smart pointers? Because we look at the Android source code, we will find that almost a lot of places have used this stuff, so we are introducing the back of the knowledge point, first look at this bar.
second, the question
So what's a smart pointer in Android? We know that the Java language of Android is developed, the Java language is not the concept of pointers, of course, Java has JNI technology, C + + has the concept of pointers, then why is it called intelligence? Whether the smart pointer is really a pointer, how to do it intelligently, we look at these problems with doubts.
In fact, the smart pointer in Android is the encapsulation of the object recycling mechanism in C + +, we know that the constructors and destructors in C + + are called when object new comes out and delete, but when we destroy an object, we need to call the DELETE keyword to destroy it manually. But in Java we do not need to care about the destruction of these objects are done by the garbage collector, so at the Android system layer, in order to achieve the effect of this automatic management of Java, the concept of smart pointers, he appeared similar to the garbage collector in Java, Or the function of the automatic release pool in OC, etc., his internal implementation is also very simple, is to use two variables to control, one is a strong reference count variable, one is a weak reference count variable, these two variables are int type, indicating how many times an object is referenced, Two variables determine whether to dispose of objects based on a specific life management cycle pattern.
Third, the source code interpretation
The main code for smart pointers in Android is: RefBase.h and RefBase.cpp two files, which are located in:
Refbase.h:android Source Directory \frameworks\native\include\utils\refbase.h
RefBase.cpp:Android Source Directory \frameworks\native\libs\utils\refbase.cpp
We can see the definition of smart pointers in RefBase.h. Smart pointers are divided into two kinds, one is SP, one is WP, as the name implies, Sp=strong pointer
Wp=weak pointer, they both have a purpose, the following will be described in detail, first look at their definition:
We see this used in C + + template technology to define, about the template if you are not familiar with it, can be considered as a generic mechanism in Java, simplifying code, increase commonality and security.
From the definition, we know that SP and WP are actually a class, not really a pointer, this solves our first confusion, the smart pointer is not the real meaning of the pointer.
We see a variable of type refbase in SP and WP class, so we're looking at what Refbase is:
Here we see that itself refbase there are two methods: Incstrong and Decstrong, this one should know that these two methods are used to manipulate the strong pointer, in the refbase within the definition of the Weakref_type class, This class has two methods: Incweak and Decweak, which should be known as the two methods used to manipulate weak pointers. We're going to take a look inside RefBase.cpp:
A weakref_impl inner class within the refbase, inheriting the Weakref_type class, has four variables inside him:
1, Mstrong: is the reference count of the record strong pointer
2. Mweak: is a reference count that records weak pointers
3, Mbase: is a variable of type Refbase
4, Mflags: Smart pointer What kind of life management cycle, the default is 0, is to use a strong life cycle to manage objects.
Then see the initialization of Weakref_impl and see:
The value of the Mstrong variable initialization is: 0x10000000
Why not use 0 as the value of the initialization, because the next need to determine whether a state is a strong reference count has been used, if used 0, then you can not distinguish between the 0 value is not used, or used over the zeroing, so here do not have to do the initialization value
The value of the initialization of the Mweak variable is: 0
The value of the initialization of the mflags variable is: 0, where 0 means to manage the life cycle of the object with a strong life management approach, and of course there are other ways to look at the definition:
There is also a weak management approach, why there are two ways, it will be said later.
Analysis here, we need to tidy up the relationship:
1, SP and WP is a class, they are used to manage the life cycle of an object, but they are modeled class, all managed objects must inherit the Refbase class, the Refbase class is called the real object, is to manage the object itself.
2, the Refbase class is the most core class, his internal weakref_impl inner class, inherits the Weakref_type class, this class we commonly called the Shadow object, and Refbase is corresponds. Weakref_impl has several variables, Mstrong is used to record the object's strong reference count, Mweak is used to record the object's weak reference count, Mbase is the refbase type, that is, the need to manage the object itself. Mflag is the way to manage the life cycle of objects.
3, from 2 we can see, refbase and Weakref_impl These two classes are interdependent, and they also correspond to each other, one is the real object, one is the Shadow object.
After talking about the relationship, we're looking at how the SP works:
Suppose you now have a class MyClass, if you want to use smart pointers to refer to objects of this class, then this class needs to meet the following two prerequisites:
1) This class is a subclass or an indirect subclass of a base class refbase;
2) This class must define a fictional constructor, that is, its constructor needs to be defined like this:
Virtual ~myclass ();
Classes that meet the above criteria can define smart pointers, which are similar to normal pointers for defining methods. For example, the normal pointer is this definition:
Smart pointers are defined like this:
Be careful not to define sp<myclass>* p_obj. Beginners are prone to make this mistake, which is actually equivalent to defining a pointer pointer. Although there is no grammatical problem, it is best to never use such a definition.
A variable that defines a smart pointer can be used like a normal pointer, including assignment, access to an object member, as a function's return value, as a function parameter, and so on. Like what:
P_obj = new MyClass (); Be careful not to write p_obj = new sp<myclass> sp<myclass> p_obj2 = p_obj; P_obj->func (); P_obj = Create_obj (); Some_func (P_obj);
Note Do not attempt to delete a smart pointer, that is, delete p_obj. Do not worry about object destruction, the most important role of smart pointers is to automatically destroy objects that are no longer used. After you do not need to use an object, assign the pointer to null directly:
P_obj = NULL;
These are strong pointers, and weak pointers are similar to strong pointers, but you cannot access the members of an object through weak pointers. The following is an example of a weak pointer:
wp<myclass> wp_obj = new MyClass (); P_obj = Wp_obj.promote (); Upgrade to a strong pointer. But it's going to be used here. Instead of->, it's the name of the pointer. wp_obj = NULL;
Smart pointers are handy, and in general it is better to use smart pointers instead of normal pointers. But it is necessary to know that a smart pointer is actually an object, not a real pointer, so its efficiency is far less than that of a normal pointer. Therefore, it is better not to use smart pointers in areas where the efficiency of the operation is sensitive.
Below we will specifically analyze refbase internal implementation, mainly look at the Incstrong,decstrong,incweak,decweak these several methods:
1, Incweak Method:
The Incweak method here is to increase the weak application count, using the Android_atomic_inc method, the atomic operation, it should be noted that the return value of this method represents the value before the increment.
2, Incstrong Method:
The method is to increase the strong reference count, and we see that we first call the Incweak method in the Weakref_impl type variable, increase the weak reference count, and then call:
Const int32_t c = Android_atomic_dec (&refs->mstrong);
To increase the strong reference count, here is an atomic operation, the return value is noted as the value before the operation. Then looking down, there is a judgment:
If the strong reference count is the initialization value (Initial_strong_value) before the operation, then here we will subtract a Initial_strong_value value from the strong application count, then the Mstrong value is 1, which is expected, Then call the Onfirstref method, which is used to initialize the operation.
3, Decweak Method:
Here we first reduce the weak reference count, if the weak reference count is 0, then you need to make the following judgment:
1, if the use of strong life cycle management methods:
1) If you have not used a strong reference to count this variable, then delete the real object directly
2) If you have used it, delete the shadow object directly
2, if the use of weak what cycle management method, directly delete the real object
It should be noted here that, because the values of Object_lifetime_mask and Object_lifetime_weak are the same as the 1, here the two to judge the way Life Management code is the same, just feel the first judge a little silly, should be write source time travel.
4, Decstrong Method:
This method, first of the strong reference count to do minus one operation, if the strong reference count is 0, then in the judgment of the object management is not a strong management method, if the real object is deleted directly, and finally call a Decweak method, reduce a weak reference count, Because in the previous Incstrong method is also called once the Incweak method, here is also the corresponding.
5, Refbase of the destruction method:
In our analysis of the Decstrong method above, we did not find the code to delete the shadow object, so when will the Shadow object be deleted? In fact, in the real object of the destruction method to do the operation.
We analyzed the above several methods, the following to tidy up:
1, Incstrong and Incweak method is relatively simple, is to add a strong reference and weak reference count, it is important to note that the Incstrong method will call the Incweak method
2, the Decweak method is a bit complicated, there are two things to do: whether to release the real object, whether to release the Shadow object:
1), if the life cycle is a weak reference to control, then you need to make a judgment here, whether the count of weak application is 0, whether to release real objects and shadow objects
2), if the life cycle is a strong reference to control, then here also to determine if the strong reference count is 0, you need to release the real object, the weak reference count is no 0, whether to release the Shadow object
From here we can see:
A weak reference count is a relational shadow object, and if the weak reference count is 0, the shadow object must be freed, but the real object does not have to be released
A strong reference count is a relational real object, and if the strong reference count is 0, the real object must be freed, but the shadow object does not necessarily release
3, Decstrong method mainly do: is to see if you want to release the real object, because the strong reference and the real object associated
4, Refbase of the destruction method: When the real object is destroyed, need to do a job is to release the Shadow object
There are two scenarios for releasing a Shadow object:
1), if the strong reference count is not used at all, then the direct release
2), if the strong reference count has been used, but the use of non-strong life cycle management, is also released
iv. Case Test
The above is actually the introduction of Android smart pointer concept and usage, but may still not understand, so in order to better understand, we need to use our own most familiar with the code to practice, from writing, from writing words not difficult, define a refbase class and weakref_ Impl class can, here I use Java to implement, the specific code here will not paste, the following will give the project, interested students can go to see:
Refbase.java is defined as follows:
One thing to note here is that the objects in Java are automatically managed, not similar to the destructor method in C + +, so here is a dealloc to simulate the destructor method:
Here the Dealloc method is actually copied OC in, haha ~ ~
Weakref_impl.java is defined as follows:
In defining a test class Testa.java:
You need to inherit the Refbase class here.
Testing is done with the test code below:
Test with two objects:
The first object to test: a strong management lifecycle approach
Here we can see the result of the operation, which meets the expectations:
If a strong lifecycle management object is used, the real object is deleted only when the strong reference count is 0, and the shadow object is deleted when the weak reference count is 0.
The second object is used to test: Weak life cycle mode
Here we can see the result of the operation, which meets the expectations:
If a weak lifecycle management object is used, the real object is deleted only if both the strong reference count and the weak reference count are 0.
For example, here we annotate a line of code:
We are running the result:
found that the real object was not deleted, and the Shadow object was not deleted. Meet expectations
Said here, but also want to say one more, is in Android4.4, in addition to these two management methods, there is another is: object_lifetime_forever, see literally, permanent, that is, if the strong reference count and the weak reference count is 0, This object can not be deleted, only manually call Delete to destroy the object, but this is abandoned after Android4.4, since this is said here, just look at it:
The Decweak method definition in the Refbase source before Android4.4 is this:
See here, with the object_lifetime_forever, because this value is 3=0x11,object_lifetime_weak this value is 1=0x01, then
Object_lifetime_forever actually contains the situation of Object_lifetime_weak, let's Change the Java code:
No matter how we invoke the various methods of DEC, there are no real objects and shadow objects removed, only the Dealloc method of invoking real objects manually. But this management method has been abandoned, so we can not care.
v. Knowledge grooming
Here we have the knowledge of smart pointers in Android, the following to organize:
1, the smart pointer in Android is not a real pointer, he is the SP and WP class object, used to manage the object's life cycle of the intermediate class.
2. Why should I use smart pointers in Android? Because the Android system layer is implemented in C/s + + and does not automatically manage the life cycle of objects, a set of life-cycle mechanisms that can automatically manage objects is developed: smart pointers
3. Three life cycle management methods for smart pointers:
1). If the object's flag bit is set to 0, the object will be deleted automatically whenever the object's strong reference count value is 0.
2). If the object's flag bit is set to Object_lifetime_weak, the object will be deleted automatically only if the object's strong reference count and the weak reference count are 0.
3). If the object's flag bit is set to Object_lifetime_forever, then the object will never be deleted automatically, who will delete the object from the new one.
Vi. complementary points of knowledge
The above mentioned knowledge points missing two, but personal feeling and this article does not matter, here simply say:
1, the smart pointer in Android is actually divided into lightweight and heavyweight, heavyweight is what we mentioned above, but also the most complex, lightweight pointer is very simple:
Here, a Mcount variable is used to control the number of references to the object.
2, the above mentioned an SP and WP two classes, we know that the SP is a real object of a pointer, you can directly use the real object of the method, WP is a shadow object, he is just a reference to real objects, can not directly use the methods of real objects, we can see from their two usages, SP is used by dot syntax, WP with the syntax, this in C + +, point syntax is the pointer,-> syntax is a reference.
So you need to upgrade WP to the SP to use the real object, then it is important to note that if the real object has been delete, then WP upgraded the SP after the object is null.
Finally, take a look at the relationship between them: REFBASE,WEAKREF_IMPL,SP,WP
Vii. Why should we introduce smart pointers
The beginning of the time has been said that the Android system layer in order to solve the automatic management of the object introduced the smart pointer mechanism, so the smart pointer is the basis of our subsequent articles, the later analysis of the system module, will find many classes are used refbase, such as binder mechanism:
This is also a module that we need to analyze later, see he used the refbase.
This article introduces the basics of Android in the system, the smart pointer knowledge point, of course, this may not be so comprehensive, but we can understand, we write an example to learn more about the smart pointer.
More details can be found here
PS: Attention, the latest Android technology real-time push
Android System chapter----Smart pointers in Android