The parcel of Android analytics

Source: Internet
Author: User

Package data, transfer across processes (via binder). Look at what this stuff is:

Parcel.java:

Public final class Parcel {    private static final Boolean debug_recycle = false;    private static final String TAG = "Parcel";    @SuppressWarnings ({"Unuseddeclaration"})    private int mnativeptr;//used by native code, non-static     /**     * Flag Indicating if {@link #mNativePtr} is allocated by this object,     * indicating that we ' re responsible for its lifecycle.     */    Private Boolean mownsnativeparcelobject;//non-static, as explained above, it identifies whether "Mnativeptr" is available, if it is assigned from Nativecode, It is to be responsible for its life cycle    private runtimeexception mstack;    private static final int pool_size = 6;    private static final parcel[] Sownedpool = new parcel[pool_size];//static, class owned, same as below. Used as a buffer pool for parcel.    private static final parcel[] Sholderpool = new Parcel[pool_size];

Here's the procedure for calling parcel's obtain ():

    Static protected final Parcel obtain () {final parcel[] pool = sholderpool;//try to fetch sholderpool from this buffer pool SYNCHR            Onized (Pool) {Parcel p;                for (int i=0; i<pool_size; i++) {//pool_size is 6 p = pool[i];                    if (P! = null) {Pool[i] = null;                    if (debug_recycle) {p.mstack = new runtimeexception ();                } p.init (obj);//Find an available (non-null), initialize the parcel return p;        }}} return new Parcel (0);//If 6 are not available (that is, buffer Chiling), the new one comes out} private Parcel (int nativeptr) {        if (debug_recycle) {mstack = new runtimeexception ();        }//log.i (TAG, "Initializing obj=0x" + integer.tohexstring (obj), mstack); Init (NATIVEPTR);//Simple Call} private void init (int nativeptr) {if (nativeptr! = 0) {mnativeptr = Nat            Iveptr; Mownsnativeparcelobject = false;       } else {mnativeptr = Nativecreate ();//Call native CODE Mownsnativeparcelobject = true;//indicates that you need to be responsible for The life cycle of this parcel object.        Several methods are followed to determine whether to release native code-generated objects based on the Boolean value. }    }

Summary: Parcel (. java) logic is very simple, from the Sholderpool or sownedpool to find not equal to null, remove to reuse. Otherwise, call native code to regenerate a parcel. Here, there are member variables for the mnativeptr and Mownsnativeparcelobject two objects to identify whether the parcel of the generated native layer needs to be freed/destroyed.

Parcel.h (. cpp) Analysis:

In Parcel.h, there are many fields. In fact, parcel can be seen as a manager managing a piece of memory.

    status_t            Merror;    The uint8_t*            mdata;//pointer, literally, should be a pointer to the data    size_t              mdatasize;//Indicates the size of the data, the size of the data already stored    size_t              mdatacapacity;//should be the capacity of memory space    mutable size_t      mdatapos;//mutable decoration, indicating that this variable to reflect the latest value in time, the analogy array position subscript
size_t* mobjects;//pointers, which can be thought of as arrays. It stores the size of each memory requested by the parcel object size_t mobjectssize;//used with the above array size_t mobjectscapacity; mutable size_t mnextobjecthint; mutable bool Mfdsknown; mutable bool Mhasfds; BOOL Mallowfds; Release_func Mowner; void* Mownercookie;

 From the above fields, it is still a classic memory management method, this generally has: the Memory start address (corresponding to the above mdata), the total memory capacity (corresponding to mdatacapacity), memory capacity (corresponding to mdatasize), the currently available memory location (MDATAPOS). In parcel, the size of each object stored in memory is further subdivided. Finer granularity.

Parcel::P arcel ()//constructor {    initstate ();} ... void parcel::initstate ()//simply assigns the initial value {Merror = No_error to each member variable    ;    Mdata = 0;    mdatasize = 0;    mdatacapacity = 0;    Mdatapos = 0;    ALOGV ("Initstate Setting data size of%p to%d\n", this, mdatasize);    ALOGV ("Initstate Setting data pos of%p to%d\n", this, mdatapos);    Mobjects = NULL;    mobjectssize = 0;    mobjectscapacity = 0;    Mnextobjecthint = 0;    Mhasfds = false;    Mfdsknown = true;    Mallowfds = true;    Mowner = NULL;}

In Setdatacapacity, setdatasize and other functions, called to Continuewrite, this function is the actual application of memory functions:

status_t Parcel::continuewrite (size_t desired) {//If shrinking, first adjust for any objects the appear//after T    He new data size.    size_t objectssize = mobjectssize;        if (desired < mdatasize) {//indicates need to shrink the requested memory capacity if (desired = = 0) {objectssize = 0; } else {while (Objectssize > 0) {if (Mobjects[objectssize-1] < desired)//Find an object with less memory size than you want                The requested memory size is break;            objectssize--; }}} if (Mowner) {//mowner is a callback function pointer//If the size is going to zero, just release the owner ' s dat        A. if (desired = = 0) {freedata ();//release data return no_error;        }//If There is a different owner, we need to take//posession.            uint8_t* data = (uint8_t*) malloc (desired);//Allocate memory if (!data) {merror = no_memory;        return no_memory;                } size_t* objects = NULL;          if (objectssize) {  objects = (size_t*) malloc (objectssize*sizeof (size_t));//Allocate objectsize*sizeof (size_t) Size of memory if (!objects) {                Merror = no_memory;            return no_memory;            }//Little hack to only acquire references on objects//We'll be keeping.            size_t oldobjectssize = mobjectssize;            Mobjectssize = objectssize;        Acquireobjects ();//Add strong and weak reference counts to each object-mobjectssize = Oldobjectssize if required;         } if (Mdata) {memcpy (data, Mdata, mdatasize < desired. mdatasize:desired);//Copy to data (new application)        } if (objects && mobjects) {memcpy (objects, Mobjects, objectssize*sizeof (size_t));        }//alogi ("Freeing data ref of%p (pid=%d) \ n", this, Getpid ());        Mowner (This, Mdata, Mdatasize, Mobjects, Mobjectssize, Mownercookie);        Mowner = NULL;        Mdata = data;        Mobjects = objects; Mdatasize = (Mdatasize < desired)? Mdatasize:desired;        ALOGV ("Continuewrite Setting data size of%p to%d\n", this, mdatasize);        mdatacapacity = desired;        Mobjectssize = Mobjectscapacity = Objectssize;    Mnextobjecthint = 0; } else if (Mdata) {if (Objectssize < mobjectssize) {//need to release refs in any objects we is D            Ropping.            Const sp<processstate> proc (processstate::self ()); for (size_t i=objectssize; i<mobjectssize; i++) {Const flat_binder_object* flat = RE                Interpret_cast<flat_binder_object*> (Mdata+mobjects[i]); if (Flat->type = = binder_type_fd) {//would need to rescan because we are having lopped off the only F                Ds Mfdsknown = false; } release_object (proc, *flat, this);//try to free the object} size_t* objects = (size            _t*) realloc (mobjects, objectssize*sizeof (size_t)); if (objects){mobjects = objects;            } mobjectssize = Objectssize;        Mnextobjecthint = 0;        }//We own the data, so we can just do a realloc ().            if (Desired > mdatacapacity) {uint8_t* data = (uint8_t*) realloc (mdata, desired);//Reallocate memory at the original Mdata location                if (data) {mdata = data;            mdatacapacity = desired;                } else if (desired > mdatacapacity) {merror = no_memory;            return no_memory;                }} else {if (Mdatasize > desired) {mdatasize = desired;            ALOGV ("Continuewrite Setting data size of%p to%d\n", this, mdatasize);                } if (Mdatapos > desired) {mdatapos = desired;            ALOGV ("Continuewrite Setting data pos of%p to%d\n", this, mdatapos);  }}} else {//This is the first data.        easy! uint8_t* data = (UINT8_t*) malloc (desired);//Direct application required size if (!data) {merror = no_memory;        return no_memory; } if (! ( Mdatacapacity = = 0 && mobjects = = NULL && mobjectscapacity = 0)) {Aloge ("continue        Write:%d/%p/%d/%d ", Mdatacapacity, Mobjects, mobjectscapacity, desired);        } mdata = data;        mdatasize = Mdatapos = 0;        ALOGV ("Continuewrite Setting data size of%p to%d\n", this, mdatasize);        ALOGV ("Continuewrite Setting data pos of%p to%d\n", this, mdatapos);    mdatacapacity = desired; } return no_error;}

Summary: The above memory allocation management is more detailed, in general, "either a new application of a piece of memory", "either reuse a piece of memory", "Free Memory", plus the object's life cycle control.

The parcel of Android analytics

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.