Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(2)

简介:

  3. 强指针

       强指针所使用的引用计数类为RefBase,它LightRefBase类要复杂多了,所以才称后者为轻量级的引用计数基类吧。我们先来看看RefBase类的实现,它定义在frameworks/base/include/utils/RefBase.h文件中:


  
  
  1. class RefBase   
  2. {   
  3. public:   
  4.     void            incStrong(const void* id) const;   
  5.     void            decStrong(const void* id) const;   
  6.    
  7.     void            forceIncStrong(const void* id) const;   
  8.    
  9.     //! DEBUGGING ONLY: Get current strong ref count.   
  10.     int32_t         getStrongCount() const;   
  11.    
  12.     class weakref_type   
  13.     {   
  14.     public:   
  15.         RefBase*            refBase() const;   
  16.    
  17.         void                incWeak(const void* id);   
  18.         void                decWeak(const void* id);   
  19.    
  20.         bool                attemptIncStrong(const void* id);   
  21.    
  22.         //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.   
  23.         bool                attemptIncWeak(const void* id);   
  24.    
  25.         //! DEBUGGING ONLY: Get current weak ref count.   
  26.         int32_t             getWeakCount() const;   
  27.    
  28.         //! DEBUGGING ONLY: Print references held on object.   
  29.         void                printRefs() const;   
  30.    
  31.         //! DEBUGGING ONLY: Enable tracking for this object.   
  32.         // enable -- enable/disable tracking   
  33.         // retain -- when tracking is enable, if true, then we save a stack trace   
  34.         //           for each reference and dereference; when retain == false, we   
  35.         //           match up references and dereferences and keep only the    
  36.         //           outstanding ones.   
  37.    
  38.         void                trackMe(bool enable, bool retain);   
  39.     };   
  40.    
  41.     weakref_type*   createWeak(const void* id) const;   
  42.    
  43.     weakref_type*   getWeakRefs() const;   
  44.    
  45.     //! DEBUGGING ONLY: Print references held on object.   
  46.     inline  void            printRefs() const { getWeakRefs()->printRefs(); }   
  47.    
  48.     //! DEBUGGING ONLY: Enable tracking of object.   
  49.     inline  void            trackMe(bool enable, bool retain)   
  50.     {   
  51.         getWeakRefs()->trackMe(enable, retain);   
  52.     }   
  53.    
  54. protected:   
  55.     RefBase();   
  56.     virtual                 ~RefBase();   
  57.    
  58.     //! Flags for extendObjectLifetime()   
  59.     enum {   
  60.         OBJECT_LIFETIME_WEAK    = 0x0001,   
  61.         OBJECT_LIFETIME_FOREVER = 0x0003   
  62.     };   
  63.    
  64.     void            extendObjectLifetime(int32_t mode);   
  65.    
  66.     //! Flags for onIncStrongAttempted()   
  67.     enum {   
  68.         FIRST_INC_STRONG = 0x0001   
  69.     };   
  70.    
  71.     virtual void            onFirstRef();   
  72.     virtual void            onLastStrongRef(const void* id);   
  73.     virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);   
  74.     virtual void            onLastWeakRef(const void* id);   
  75.    
  76. private:   
  77.     friend class weakref_type;   
  78.     class weakref_impl;   
  79.    
  80.     RefBase(const RefBase& o);   
  81.     RefBase&        operator=(const RefBase& o);   
  82.    
  83.     weakref_impl* const mRefs;   
  84. };   

   RefBase类和LightRefBase类一样,提供了incStrong和decStrong成员函数来操作它的引用计数器;而RefBase类与LightRefBase类最大的区别是,它不像LightRefBase类一样直接提供一个整型值(mutable volatile int32_t mCount)来维护对象的引用计数,前面我们说过,复杂的引用计数技术同时支持强引用计数和弱引用计数,在RefBase类中,这两种计数功能是通过其成员变量mRefs来提供的。

     RefBase类的成员变量mRefs的类型为weakref_impl指针,它实现在frameworks/base/libs/utils/RefBase.cpp文件中:


  
  
  1. class RefBase::weakref_impl : public RefBase::weakref_type   
  2. {   
  3. public:   
  4.     volatile int32_t    mStrong;   
  5.     volatile int32_t    mWeak;   
  6.     RefBase* const      mBase;   
  7.     volatile int32_t    mFlags;   
  8.    
  9.    
  10. #if !DEBUG_REFS   
  11.    
  12.     weakref_impl(RefBase* base)   
  13.         : mStrong(INITIAL_STRONG_VALUE)   
  14.         , mWeak(0)   
  15.         , mBase(base)   
  16.         , mFlags(0)   
  17.     {   
  18.     }   
  19.    
  20.     void addStrongRef(const void* /*id*/) { }   
  21.     void removeStrongRef(const void* /*id*/) { }   
  22.     void addWeakRef(const void* /*id*/) { }   
  23.     void removeWeakRef(const void* /*id*/) { }   
  24.     void printRefs() const { }   
  25.     void trackMe(bool, bool) { }   
  26.    
  27. #else   
  28.     weakref_impl(RefBase* base)   
  29.         : mStrong(INITIAL_STRONG_VALUE)   
  30.         , mWeak(0)   
  31.         , mBase(base)   
  32.         , mFlags(0)   
  33.         , mStrongRefs(NULL)   
  34.         , mWeakRefs(NULL)   
  35.         , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)   
  36.         , mRetain(false)   
  37.     {   
  38.         //LOGI("NEW weakref_impl %p for RefBase %p", this, base);   
  39.     }   
  40.    
  41.     ~weakref_impl()   
  42.     {   
  43.         LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL"Strong references remain!");   
  44.         LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL"Weak references remain!");   
  45.     }   
  46.    
  47.     void addStrongRef(const void* id)   
  48.     {   
  49.         addRef(&mStrongRefs, id, mStrong);   
  50.     }   
  51.    
  52.     void removeStrongRef(const void* id)   
  53.     {   
  54.         if (!mRetain)   
  55.             removeRef(&mStrongRefs, id);   
  56.         else   
  57.             addRef(&mStrongRefs, id, -mStrong);   
  58.     }   
  59.    
  60.     void addWeakRef(const void* id)   
  61.     {   
  62.         addRef(&mWeakRefs, id, mWeak);   
  63.     }   
  64.     void removeWeakRef(const void* id)   
  65.     {   
  66.         if (!mRetain)   
  67.             removeRef(&mWeakRefs, id);   
  68.         else   
  69.             addRef(&mWeakRefs, id, -mWeak);   
  70.     }   
  71.    
  72.     void trackMe(bool track, bool retain)   
  73.     {   
  74.         mTrackEnabled = track;   
  75.         mRetain = retain;   
  76.     }   
  77.    
  78.     ......   
  79.    
  80. private:   
  81.     struct ref_entry   
  82.     {   
  83.         ref_entry* next;   
  84.         const void* id;   
  85. #if DEBUG_REFS_CALLSTACK_ENABLED   
  86.         CallStack stack;   
  87. #endif   
  88.         int32_t ref;   
  89.     };   
  90.    
  91.     void addRef(ref_entry** refs, const void* id, int32_t mRef)   
  92.     {   
  93.         if (mTrackEnabled) {   
  94.             AutoMutex _l(mMutex);   
  95.             ref_entry* ref = new ref_entry;   
  96.             // Reference count at the time of the snapshot, but before the   
  97.             // update.  Positive value means we increment, negative--we   
  98.             // decrement the reference count.   
  99.             ref->ref = mRef;   
  100.             ref->id = id;   
  101. #if DEBUG_REFS_CALLSTACK_ENABLED   
  102.             ref->stack.update(2);   
  103. #endif   
  104.    
  105.             ref->next = *refs;   
  106.             *refs = ref;   
  107.         }   
  108.     }   
  109.    
  110.     void removeRef(ref_entry** refs, const void* id)   
  111.     {   
  112.         if (mTrackEnabled) {   
  113.             AutoMutex _l(mMutex);   
  114.    
  115.             ref_entry* ref = *refs;   
  116.             while (ref != NULL) {   
  117.                 if (ref->id == id) {   
  118.                     *refs = ref->next;   
  119.                     delete ref;   
  120.                     return;   
  121.                 }   
  122.    
  123.                 refs = &ref->next;   
  124.                 ref = *refs;   
  125.             }   
  126.    
  127.             LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!",   
  128.                 id, mBase, this);   
  129.         }   
  130.     }   
  131.    
  132.     ......   
  133.    
  134.     Mutex mMutex;   
  135.     ref_entry* mStrongRefs;   
  136.     ref_entry* mWeakRefs;   
  137.    
  138.     bool mTrackEnabled;   
  139.     // Collect stack traces on addref and removeref, instead of deleting the stack references   
  140.     // on removeref that match the address ones.   
  141.     bool mRetain;   
  142.    
  143.     ......   
  144. #endif   
  145. };   

这个类看起来实现得很复杂,其实不然,这个类的实现可以分成两部分:

  1. #if !DEBUG_REFS  
  2.   
  3. ......  
  4.   
  5. #else  

  编译指令之间的这部分源代码是Release版本的源代码,它的成员函数都是空实现;

  1. #else   
  2.   
  3. ......  
  4.   
  5. #endif  

   编译指令之间的部分源代码是Debug版本的源代码,它的成员函数都是有实现的,实现这些函数的目的都是为了方便开发人员调试引用计数用的,除此之外,还在内部实现了一个结构体ref_entry:


  
  
  1. struct ref_entry   
  2. {   
  3.     ref_entry* next;   
  4.     const void* id;   
  5. #if DEBUG_REFS_CALLSTACK_ENABLED   
  6.     CallStack stack;   
  7. #endif   
  8.     int32_t ref;   
  9. };   

   这个结构体也是为了方便调试而使用的,我们可以不关注这部分用于调试的代码。

        总的来说,weakref_impl类只要提供了以下四个成员变量来维护对象的引用计数:


  
  
  1. volatile int32_t    mStrong;   
  2. volatile int32_t    mWeak;   
  3. RefBase* const      mBase;   
  4. volatile int32_t    mFlags;   

   其中mStrong和mWeak分别表示对象的强引用计数和弱引用计数;RefBase类包含了一个weakref_impl类指针mRefs,而这里的weakref_impl类也有一个成员变量mBase来指向它的宿主类RefBase;mFlags是一个标志位,它指示了维护对象引用计数所使用的策略,后面我们将会分析到,它的取值为0,或者以下的枚举值:


  
  
  1. //! Flags for extendObjectLifetime()   
  2.     enum {   
  3.         OBJECT_LIFETIME_WEAK    = 0x0001,   
  4.         OBJECT_LIFETIME_FOREVER = 0x0003   
  5.     };   

这里我们还需要注意的一点的是,从weakref_impl的类名来看,它应该是一个实现类,那么,就必然有一个对应的接口类,这个对应的接口类的就是RefBase类内部定义的weakref_type类了,这是一种把类的实现与接口定义分离的设计方法。学习过设计模式的读者应该知道,在设计模式里面,非常强调类的接口定义和类的实现分离,以便利于后续扩展和维护,这里就是用到了这种设计思想。

 

        说了这多,RefBase类给人的感觉还是挺复杂的,不要紧,我们一步步来,先通过下面这个图来梳理一下这些类之间的关系:

 从这个类图可以看出,每一个RefBase对象包含了一个weakref_impl对象,而weakref_impl对象实现了weakref_type接口,同时它可以包含多个ref_entry对象,前面说过,ref_entry是调试用的一个结构体,实际使用中可以不关注。





本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966559,如需转载请自行联系原作者

目录
相关文章
|
12天前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
38 15
Android 系统缓存扫描与清理方法分析
|
3天前
|
算法 JavaScript Android开发
|
6天前
|
安全 搜索推荐 Android开发
揭秘安卓与iOS系统的差异:技术深度对比
【10月更文挑战第27天】 本文深入探讨了安卓(Android)与iOS两大移动操作系统的技术特点和用户体验差异。通过对比两者的系统架构、应用生态、用户界面、安全性等方面,揭示了为何这两种系统能够在市场中各占一席之地,并为用户提供不同的选择。文章旨在为读者提供一个全面的视角,理解两种系统的优势与局限,从而更好地根据自己的需求做出选择。
19 2
|
14天前
|
安全 搜索推荐 Android开发
深入探索安卓与iOS系统的差异及其对用户体验的影响
在当今的智能手机市场中,安卓和iOS是两大主流操作系统。它们各自拥有独特的特性和优势,为用户提供了不同的使用体验。本文将深入探讨安卓与iOS系统之间的主要差异,包括它们的设计理念、用户界面、应用生态以及安全性等方面,并分析这些差异如何影响用户的使用体验。
|
14天前
|
安全 搜索推荐 Android开发
揭秘iOS与Android系统的差异:一场技术与哲学的较量
在当今数字化时代,智能手机操作系统的选择成为了用户个性化表达和技术偏好的重要标志。iOS和Android,作为市场上两大主流操作系统,它们之间的竞争不仅仅是技术的比拼,更是设计理念、用户体验和生态系统构建的全面较量。本文将深入探讨iOS与Android在系统架构、应用生态、用户界面及安全性等方面的本质区别,揭示这两种系统背后的哲学思想和市场策略,帮助读者更全面地理解两者的优劣,从而做出更适合自己的选择。
|
5天前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
5天前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
7天前
|
安全 Android开发 iOS开发
安卓系统与iOS系统的比较####
【10月更文挑战第26天】 本文将深入探讨安卓(Android)和iOS这两大主流移动操作系统的各自特点、优势与不足。通过对比分析,帮助读者更好地理解两者在用户体验、应用生态、系统安全等方面的差异,从而为消费者在选择智能手机时提供参考依据。无论你是技术爱好者还是普通用户,这篇文章都将为你揭示两大系统背后的故事和技术细节。 ####
19 0
|
1月前
|
IDE Android开发 iOS开发
探索安卓与iOS系统的技术差异:开发者的视角
本文深入分析了安卓(Android)与苹果iOS两大移动操作系统在技术架构、开发环境、用户体验和市场策略方面的主要差异。通过对比这两种系统的不同特点,旨在为移动应用开发者提供有价值的见解,帮助他们在不同平台上做出更明智的开发决策。
|
1月前
|
Ubuntu Shell API
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a