2022年android智能指针详解[收 .pdf
《2022年android智能指针详解[收 .pdf》由会员分享,可在线阅读,更多相关《2022年android智能指针详解[收 .pdf(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、研究 Android 的时候,经常会遇到sp、wp 的东西,网上一搜,原来是android 封装了 c+中对象回收机制。说明:1.如果一个类想使用智能指针,那么必须满足下面两个条件:a.该类是虚基类RefBase 的子类或间接子类b.该类必须定义虚构造函数。如virtual MyClass();2.本文以类 BBinder 来进行说明,其余类使用sp 或 wp 的情况类似3.代码路径:frameworks/base/libs/utils/RefBase.cpp frameworks/base/include/utils/RefBase.h 一、calss BBinder 类说明class Re
2、fBase class IBinder class BpBinder class BBinder class BBinder:public IBinder .protected:virtual BBinder();.class IBinder:public virtual RefBase .protected:inline virtual IBinder().由上,可以看出BBinder 和 IBinder 都是以 public 的方式继承于虚基类RefBase 的。二、sp wp 对象的建立过程解析:sp BB_ptr(new BBinder);这是一条定义sp 指针 BB_ptr 的语句,
3、他只想的对象是一个BBinder 对象。如图所示。名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 11 页 -1首先看一下new BBinder 时都做了什么,特别是和该机制相关的初始化。c+中创建一个对象时,需要调用去构造函数,对于继承类,则是先调用其父类的构造函数,然后才会调用本身的构造函数。这里new 一个 BBinder 对象时,顺序调用了:RefBase:RefBase():mRefs(new weakref_impl(this)inline IBinder()BBinder:BBinder():mExtras(NULL)主要关注的是RefBase 的构造函数,名师资料
4、总结-精品资料欢迎下载-名师精心整理-第 2 页,共 11 页 -可以看出他是通过new weakref_impl(this)的结果来初始化私有成员mRefs 这里的 this 指向 BBinder 对象自身,class weakref_impl继承于类 RefBase 的内嵌类 weakref_type,然后该类weakref_impl又被类 RefBase 引用。类 weakref_impl的构造函数如下:weakref_impl(RefBase*base):mStrong(INITIAL_STRONG_VALUE)/1 28,mWeak(0),mBase(base)/new BBinde
5、r 指针,mFlags(0),mStrongRefs(NULL)/sp 引用链表指针,mWeakRefs(NULL)/wp 引用链表指针,mTrackEnabled(!DEBUG_REFS_ENABLED_BY_DEFAULT)/1,mRetain(false)2new BBinder 返回的是 BBinder 对象的指针,如:sp BB_ptr(0 x?);sp 实际上是一个类模板,这条语句最终是要建立一个sp 的实例化对象,叫模板类BB_ptr 这里生成BB_ptr 对象所调用的构造函数是:template sp:sp(T*other):m_ptr(other)if(other)other
6、-incStrong(this);BB_ptr 对象的私有指针指向刚刚前面生成的BBinder 对象。接着调用函数incStrong(),该函数是RefBase 类的成员函数,在子类中没有被重载,所以这里 other-incStrong(this)的调用实际上是调用基类成员函数incStrong(this),这个 this 值是指向 sp 对象 BB_ptr 的指针。现在转去查看该成员函数的实现。void RefBase:incStrong(const void*id)const weakref_impl*const refs=mRefs;/*取得 BBinder 对象基类中的私有只读指针mR
7、efs*/refs-addWeakRef(id);/*调用 weakref_impl类定义时实现的成员函数addWeakRef,见下注释 1*/refs-incWeak(id);/*调用 weakref_impl类的基类 weakref_type成员函数 incWeak,见下注释 2*/refs-addStrongRef(id);/调用 weakref_impl类定义时实现的成员函数addStrongRef,见下注释 1 const int32_t c=Android _atomic_inc(&refs-mStrong);/*该函数实际将refs-mStrong值加 1,也就是增加强引用计数值
8、。但是返回值为refs-mStrong-1*/LOG_ASSERT(c 0,incStrong()called on%p after last strong ref,refs);#if PRINT_REFS 名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 11 页 -LOGD(incStrong of%p from%p:cnt=%dn,this,id,c);#endif if(c!=INITIAL_STRONG_VALUE)return;/*c=INITIAL_STRONG_VALUE,第一个强引用产生的时候才会出现这个情况*/Android _atomic_add(-INITI
9、AL_STRONG_VALUE,&refs-mStrong);/*返回值为 INITIAL_STRONG_VALUE,refs-mStrong值变成 1*/const_cast(this)-onFirstRef();/*注释 1*/void addWeakRef(const void*id)addRef(&mWeakRefs,id,mWeak);void addStrongRef(const void*id)addRef(&mStrongRefs,id,mStrong);addRef()是类 weakref_impl的私有成员函数,addWeakRef()函数引用的是public 成员变量,而
10、addRef()函数可以操作私有数据。struct ref_entry ref_entry*next;const void*id;int32_t ref;void addRef(ref_entry*refs,const void*id,int32_t mRef)if(mTrackEnabled)AutoMutex _l(mMutex);ref_entry*ref=new ref_entry;ref-ref=mRef;ref-id=id;ref-next=*refs;*refs=ref;/*新出现的 ref_entry结构体加入到链表头上,如果有n 个 sp 指针指向同一个目标对象那么这里就有n
11、 个 ref_entry结构体加入到这个单链表中,该结构体记录着如下数据 1.id 域记录着对应的sp 强指针类对象的this 值名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 11 页 -2.ref 域记录的是当前sp 强指针类对象是第几个引用目标对象的指针 3.next 域指向下一个指向目标对象的sp 强指针对应的ref_entry结构体类 RefBase 的嵌套类 weakref_type的子类的私有数据mRefs 的私有二级指针成员mWeakRefs 指向的是最后一个 sp 强指针对应的ref_entry结构体指针。总结一下:一个目标对象,可能被n 个 sp 强指针指向,
12、那么就存在n 个 class sp 对象,同时每一个sp 对象在目标对象的虚基类对象的成员类mRefs 的私有二级指针成员mWeakRefs 登记了一个 ref_entry结构体,这些ref_entry结构体的地址都是由该链表管理,每一个 ref_entry结构体和哪一个sp 对象对应,也由该链表管理。同时链接数就是该链表节点的个数 */*注释 1*/*注释 2*/void RefBase:weakref_type:incWeak(const void*id)weakref_impl*const impl=static_cast(this);/强制类型转换,将基类指针转换成子类指针impl-a
13、ddWeakRef(id);/调用类 weakref_impl成员函数 addWeakRef(),产生一个ref_entry结构体挂载mWeakRefs 链表上const int32_t c=Android _atomic_inc(&impl-mWeak);/*impl-mWeak加 1,表示已存在一个weak 引用。但返回值c 为操作前的结果*/LOG_ASSERT(c=0,incWeak called on%p after last weak ref,this);/*注释 2*/3上面是定义一个sp 指针,下面看看定义一个wp 指针式如何实现的。wp BB_wp_ptr(BB_ptr);下
14、面是 wp 类对应上面定义类型的构造函数 template wp:wp(const sp&other):m_ptr(other.m_ptr)if(m_ptr)m_refs=m_ptr-createWeak(this);this 指针是指向wp 对象的。createWeak()函数是 RefBase 类的成员函数。RefBase:weakref_type*RefBase:createWeak(const void*id)const mRefs-incWeak(id);名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 11 页 -return mRefs;mRefs 指向的是第二步骤中
15、产生的weakref_impl对象,调用基类weakref_type的成员函数incWeak()void RefBase:weakref_type:incWeak(const void*id)weakref_impl*const impl=static_cast(this);impl-addWeakRef(id);const int32_t c=Android _atomic_inc(&impl-mWeak);/*impl-mWeak有加 1,但返回值为操作前的结果*/LOG_ASSERT(c=0,incWeak called on%p after last weak ref,this);三、
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年android智能指针详解收 2022 android 智能 指针 详解
限制150内