现在的位置: 首页 > 综合 > 正文

android的常见类(1)

2013年04月26日 ⁄ 综合 ⁄ 共 2945字 ⁄ 字号 评论关闭

 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。

 

 

抱歉!评论已关闭.