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,如需转载请自行联系原作者

目录
相关文章
|
2月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
252 4
|
2月前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
4月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统无疑是主角。它们各自拥有独特的特点和优势,为开发者提供了不同的开发环境和工具。本文将深入浅出地探讨安卓和iOS开发环境的主要差异,包括开发工具、编程语言、用户界面设计、性能优化以及市场覆盖等方面,旨在帮助初学者更好地理解两大平台的开发特点,并为他们选择合适的开发路径提供参考。通过比较分析,我们将揭示不同环境下的开发实践,以及如何根据项目需求和目标受众来选择最合适的开发平台。
59 2
|
1月前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
36 8
|
3月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
104 15
Android 系统缓存扫描与清理方法分析
|
2月前
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
61 1
|
3月前
|
存储 Linux Android开发
Android底层:通熟易懂分析binder:1.binder准备工作
本文详细介绍了Android Binder机制的准备工作,包括打开Binder驱动、内存映射(mmap)、启动Binder主线程等内容。通过分析系统调用和进程与驱动层的通信,解释了Binder如何实现进程间通信。文章还探讨了Binder主线程的启动流程及其在进程通信中的作用,最后总结了Binder准备工作的调用时机和重要性。
Android底层:通熟易懂分析binder:1.binder准备工作
|
4月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
175 3
|
3月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
4月前
|
安全 Linux Android开发
探索安卓与iOS的安全性差异:技术深度分析
本文深入探讨了安卓(Android)和iOS两个主流操作系统平台在安全性方面的不同之处。通过比较它们在架构设计、系统更新机制、应用程序生态和隐私保护策略等方面的差异,揭示了每个平台独特的安全优势及潜在风险。此外,文章还讨论了用户在使用这些设备时可以采取的一些最佳实践,以增强个人数据的安全。

热门文章

最新文章