android中常见的类RefBase,sp,wp,Looper和handler。

RefBase是android中的基本类,类似java中的CObject类,android中的所有类都是此类的子类,当然,sp,wp是从RefBase中派生而来,这两个类的功能是利用
引用计数的方法控制对象生命周期。

(1)Refbase类

Refbase构造函数:

RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}

refbase的成员变量 mRefs,称之为RefBase类的影子对象。类型weakref_impl 。class weakref_impl是引用计数管理的管件类。分析weakref_impl的构造函数:
class weakref_impl(RefBase * base):mStrong(INITIAL_STRONG_VALUE)//强引用计数 ,初始值为0x1000000
:mWeak(0)//弱引用计数,初始化为0
:mBase(base)//该 影子对象所指的实际对象。
:mFlag(0)
:mStrongRefs(NULL)
{

}

refbase类的构造函数中完成类对象创建的同时创建出一个weakref_impl类型的影子对象。

例子分析sp,wp
代码:
calss ohter :public RefBase
{
}

int main()
{
A* PA = new A;

sp<A> spA(pA);
wp<A> wp(spA);
}

}
(2)sp类

sp的构造函数:
sp是一个模板类,

template<typename T>
sp<T>::sp (T* ohter) // ohter指的是上例中创建的类对象
:m_ptr(ohter) // 这个变量保留ohter的指针
{
if (ohter) ohter ->incStrong(this);
}
这里需要注意的是调用的这个incStrong()是RefBase的成员函数。
函数如下:

void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;//影子对象
refs->incWeak(id);//函数调用完成后,此时弱引用数+ 1 (incWeak()中的影子对象+ 1)
refs->addStrongRef(id);//不干工作
//原子操作,结果是c保持原值0x1000000,变化是mStrong + 1
const int32_t c = android_atomic_inc(&refs->mStrong);

......

//这步处理之后mStrong变成1
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
// 首次引用时调用onFirstRef()完成一些初始化
refs->mBase->onFirstRef();
}

sp 构造函数完成后,即通过原子操作完成强引用计数和弱引用计数均+1的操作。
(3)wp类
template<typename U> wp(U* other);
template<typename U> wp(const sp<U>& other);
template<typename U> wp(const wp<U>& other);

例子中使用是template<typename U> wp(const sp<U>& other);
模板:
template<typename T> template<typename U>
wp<T>::wp(const sp<U>& other)
: m_ptr(other.m_ptr)// 成员变量指针用来保存实际对象,指向实际对象
{
if (m_ptr) {
m_refs = m_ptr->createWeak(this);
}
}

函数调用中影子对象 m_refs = m_ptr->createWeak(this);调用的还是Refbase的函数,完成的工作是使弱引用计数+1,
这时,显示,若引用计数为2,强引用计数为1.

关于wp,sp的析构过程:

wp:
template<typename T>
wp<T>::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}
decWeak()这个函数还是调用的基类refbase的函数,最终的结果是弱引用计数-1。此时干掉的只是弱引用,sp对象仍然存在,此时保持的是强弱引用计数的值都是1,就是说影子对象还存在,即表示,实际对象也存在,此时实际对象和影子对象都占据内存。

接下来是sp的析构,同理,根据源代码分析可知,此时sp的析构完成的工作是使强弱引用计数均-1。

根据分析可知,要彻底的消灭创建出来的对象,包括衍生出来的影子对象,都是由强弱引用计数控制的,当sp析构时,强引用操作的原则对象使得mStrong==0,这时导致实际对象delete this,即实际对象销毁,但是影子对象依然存在,继续分析代码可知最后随着sp的析构,影子对象也被干掉。

就是说,实际对象和影子对象的灭亡都是由其中的强弱引用计数控制的。根据代码可知,影子对象中的一个成员变量,flag,作用:当flag == 0时,强引用计数==0,导致实际对象delete,若引用计数==0,影子对象delete.

(4)wp转换成sp

wp可以转化成sp,但是sp不能转换成wp。将wp转换成sp之后,相当于又增加了一个强引用。由弱生强之后,强弱引用计数均增加,这时,强引用计数为1,弱引用计数为2.

结论:

sp 和wp这两个android中表示强弱指针的类,它们通过成员变量m_pt指向它所指向的实际对象,由于所有的android类对象都是RefBase的派生,所以,这时候可以关联到实际对象,实际对象同时创建了影子对象,在sp和wp中调用实际对象的函数,这些函数是操作的影子对象,使影子对象中的强弱引用计数增加减,最终利用强弱引用计数的变化达到实际对象和影子对象的销毁,实现了,分配空间的自动回收工作。所以说,这样的强弱指针,可以完成类对象的自动回收工作,不用手工完成,解除程序员后顾之忧。

(5)轻量级的引用计数控制类 LightRefBase

LightRefBase类是一个类模板,支持的是sp的操作,于只有一个mCount控制变量,相当于mStrong,完成的是incStrong和decStrong。

更多相关文章

  1. android UI更新问题 Thread和Looper以及Handler和Message详解 An
  2. Handler与异步消息处理
  3. Android图形基础
  4. Android中StateListDrawable的种类(状态的种类)
  5. Android(安卓)OpenSL介绍 并实现播放PCM功能
  6. 第一篇:Android(安卓)Studio 打包及引用 AAR(可能是史上最详细的 )
  7. 理解Android回调函数
  8. 【Android(安卓)内存优化】Bitmap 长图加载 ( BitmapRegionDecod
  9. android XMl 解析神奇xstream 三: 把复杂对象转换成 xml

随机推荐

  1. Android 手电筒 附源码
  2. Android简单练习(TableLayout)
  3. Android P SystemUI添加VoWiFi Tile
  4. android录音和得到音量
  5. Android综合小练习Fragment,解析,Handler
  6. Android动态添加删除recycleview并动态保
  7. android 系统文件目录结构
  8. Android仿美图秀秀给图片加框
  9. Android:计算剩余内存
  10. Android切换横屏竖屏生命周期变化