Android -- sp、wp强弱指针的原理简介
我们知道,Android的native层代码基本都是C/C++的天下;基于这种特点,在native层中大量使用指针来操作对象就在所难免了。由于C/C++需要程序员手动操作管理内存,这就使程序出现内存管理问题的概率大大提高。所以,在Android中就提出了一种新的指针概念:强指针(sp)、弱指针(wp)来代替普通的指针;这种指针基于引用计数,来智能地管理对象指针,并不需要程序员做过多的内存管理操作。
在Android中,为了使用sp、wp,我们设计的类都必须是一个类的子类,那就是RefBase,我们看它的类定义:
//sp和wp已经深入融合到了Android系统native代码中,如果我们想使一个类型支持sp和wp操作,就必须
//让这个类继承RefBase类;从某一个角度来说,RefBase类很类似于Java中的Object类,因为它是所有native类的父类
class RefBase
{
public:
void incStrong(const void* id) const;//强引用计数方法
void decStrong(const void* id) const;//强引用计数方法
void forceIncStrong(const void* id) const;
//! DEBUGGING ONLY: Get current strong ref count.
int32_t getStrongCount() const;
//RefBase的一个内部类型,它是管理引用计数的一个重要辅助类
class weakref_type
{
public:
RefBase* refBase() const;
void incWeak(const void* id);//弱引用计数方法
void decWeak(const void* id);//弱引用计数方法
// acquires a strong reference if there is already one.
bool attemptIncStrong(const void* id);
// acquires a weak reference if there is already one.
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
// for proper use.
bool attemptIncWeak(const void* id);
//! DEBUGGING ONLY: Get current weak ref count.
int32_t getWeakCount() const;
//! DEBUGGING ONLY: Print references held on object.
void printRefs() const;
//! DEBUGGING ONLY: Enable tracking for this object.
// enable -- enable/disable tracking
// retain -- when tracking is enable, if true, then we save a stack trace
// for each reference and dereference; when retain == false, we
// match up references and dereferences and keep only the
// outstanding ones.
void trackMe(bool enable, bool retain);
};
weakref_type* createWeak(const void* id) const;
weakref_type* getWeakRefs() const;
//! DEBUGGING ONLY: Print references held on object.
inline void printRefs() const { getWeakRefs()->printRefs(); }
//! DEBUGGING ONLY: Enable tracking of object.
inline void trackMe(bool enable, bool retain)
{
getWeakRefs()->trackMe(enable, retain);
}
typedef RefBase basetype;
protected:
RefBase();
virtual ~RefBase();
//! Flags for extendObjectLifetime()
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
void extendObjectLifetime(int32_t mode);
//! Flags for onIncStrongAttempted()
enum {
FIRST_INC_STRONG = 0x0001
};
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
virtual void onLastWeakRef(const void* id);
private:
friend class weakref_type;
class weakref_impl;
RefBase(const RefBase& o);
RefBase& operator=(const RefBase& o);
private:
friend class ReferenceMover;
static void renameRefs(size_t n, const ReferenceRenamer& renamer);
static void renameRefId(weakref_type* ref,
const void* old_id, const void* new_id);
static void renameRefId(RefBase* ref,
const void* old_id, const void* new_id);
weakref_impl* const mRefs;//用于引用计数
};
类中声明的inc、dec前缀的方法,就是用于操控引用计数的方法,某个指针的引用计数的状态就觉得了它自身的生命周期:何时被回收。
sp、wp虽然叫做强弱指针,但它们实际都是一个模板类,分别看它们的声明:
template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;
inline wp() : m_ptr(0) { }
wp(T* other);
wp(const wp<T>& other);
wp(const sp<T>& other);
template<typename U> wp(U* other);
template<typename U> wp(const sp<U>& other);
template<typename U> wp(const wp<U>& other);
~wp();
...
// promotion to sp
sp<T> promote() const;
// Reset
void clear();
// Accessors
inline weakref_type* get_refs() const { return m_refs; }
inline T* unsafe_get() const { return m_ptr; }
...
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
T* m_ptr;
weakref_type* m_refs;
};
template <typename T>
class sp
{
public:
inline sp() : m_ptr(0) { }
sp(T* other);
sp(const sp<T>& other);
template<typename U> sp(U* other);
template<typename U> sp(const sp<U>& other);
~sp();
...
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};
一、sp、wp的创建和析构过程
接着,我们从一个最常见的示例出发,来看看我们创建wp、sp指针时,都做了哪些工作:
class Example : public RefBase {};
int main()
{
Example* exa = new Example;//1、创建Example指针对象
sp<Example> sP(exa);//2、创建sP
wp<Example> wP(exa);//3、创建wP
return 0;
}
第一步:
定义一个RefBase的子类类型,作为sp、wp的模板类型,并创建它的一个指针对象。Example没有任何成员,使用它使用父类的构造函数:
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
weakref_impl* const mRefs;//RefBase::weakref_type子类,用于管理引用计数
mRefs是RefBase::weakref_type类型的指针,这里以当前指针对象为参数初始化了该指针:
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)//初始化强引用计数值
, mWeak(0)//初始化若引用计数值
, mBase(base)//mBase是RefBase*类型,指向exa
, mFlags(0)
, mStrongRefs(NULL)
, mWeakRefs(NULL)
, mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
, mRetain(false)
{
}
初始化完成后,第一步的工作就结束了,它主要创建了一个引用计数管理对象,并进行了一些初始化工作。
接着看第二步:
sp的构造函数有多个,这里只看最常见的接收指针类型参数的部分:
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {//m_ptr指向模板类型的实例指针
if (other)
other->incStrong(this);
}
这里模板类型T就是Example,简单地调用Example的incStrong()方法。由Example的继承关系可知,实际调用的是父类RefBase的同名方法:
void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;//RefBase::weakref_type子类
refs->incWeak(id);//通过原子操作,为弱引用计数值+1;第一次引用时,对象的弱引用计数值为1
refs->addStrongRef(id);//调试作用
const int32_t c = android_atomic_inc(&refs->mStrong);//通过原子操作,为强引用计数值+1,并返回操作之前的旧值;初始值是 1 << 28
ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
#if PRINT_REFS
ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
if (c != INITIAL_STRONG_VALUE) {//( 1 << 28 ),如果不为初始值,说明,该对象已经被强引用了。这时,直接return;
return;
}
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);//再执行一次原子加法操作,第一次引用时,此时强引用计数值应为1
refs->mBase->onFirstRef();//然后在调用该模板类型对象的onFirstRef()方法,这里我们要注意:当一个对象第一次被强引用时,会调用该方法;所以,我们可以在
//该函数中做一些初始化操作,此时作用类似于构造函数,Media部分就有这种设计.
}
至此,一个强引用的创建过程就结束了;我们要记住的是:
- 一个sp构造完成后,它内部的对该对象的强引用和弱引用计数都为1
- 一个sp构造时,会调用一次模板类型的onFirstRef()函数
再看第三步:
wp的创建过程,先看它的构造函数实现:
template<typename T>
wp<T>::wp(T* other)
: m_ptr(other)//m_ptr是指向模板类型的一个指针成员变量
{
if (other) m_refs = other->createWeak(this);//m_refs是指向RefBase::weakref_type类型的指针,它管理引用计数
}
跟前面类似,调用:
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id);//mRefs是RefBase::weakref_type子类型
return mRefs;
}
调用RefBase::weakref_type::incWeak():
void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);//weakref_impl是RefBase::weakref_type的子类
impl->addWeakRef(id);//调试作用
const int32_t c __unused = android_atomic_inc(&impl->mWeak);//将impl的mWeak计数值,通过原子操作+1;对于第一次被引用,此时该对象的弱引用计数为2
ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
整个sp、wp的构建过程就结束了,看到这里,我们应该知道:
- sp中有一个模板类型指针,指向一个实际的模板类型指针变量;而wp中除了有这样一个变量外,还有一个成员变量指向RefBase::weakref_type类型,用于管理引用计数
- 当一个实际对象经过sp和wp创建后,它的强引用计数值为1,而弱引用计数值为2
构建过程完成后,我们还有必要看下sp、wp的析构过程,看看实际对象的指针什么时候会被释放。对象解析的顺序与声明相反,所以先看wp的析构过程:
template<typename T>
wp<T>::~wp()
{
if (m_ptr) m_refs->decWeak(this);//m_refs是RefBase::weakref_type类型
}
直接看它的decWeak()函数:
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);//调试不管
const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为1;原值是2
ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;//c=2,return掉
//判断了一些生命周期标志的情况,如果c值是1,则表明弱引用计数值已经是0了,对象没有被弱引用,此时需要考虑声明周期以及对象释放操作
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlive the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong == INITIAL_STRONG_VALUE) {//如果我们的强引用计数为默认值,则表示该对象没有强引用,需要删除对象
// Special case: we never had a strong reference, so we need to
// destroy the object now.
delete impl->mBase;
} else {//否则删除引用计数管理对象
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
// less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
impl->mBase->onLastWeakRef(id);
if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
// this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
delete impl->mBase;//删除实际对象
}
}
}
此时模板对象的强引用和弱引用计数值皆为1。
再看sp的析构函数:
template<typename T>
sp<T>::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
调用:
void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);//调试不管
const int32_t c = android_atomic_dec(&refs->mStrong);//强引用计数值减1,此时强引用计数为0;c = 1
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
if (c == 1) {
refs->mBase->onLastStrongRef(id);//函数体为空,无任何操作
if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {//自身对象有可能会被删除;mFlags默认值为0,未设置时条件成立
delete this;//删除自身,这里的this就是实际模板对象,会触发Example的析构调用
}
}
refs->decWeak(id);//此时弱引用计数为1,强引用计数值已经为0,再对弱引用计数做一次原子减法
}
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);//调试不管
const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为0;原值c=1
ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;//c=1
//判断了一些生命周期标志的情况,如果我们没有设置mFlags,则满足此项
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {//此时强弱引用计数皆为0,再将计数管理对象删除
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlive the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong == INITIAL_STRONG_VALUE) {//此时不满足
// Special case: we never had a strong reference, so we need to
// destroy the object now.
delete impl->mBase;
} else {//删除引用计数管理对象
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
// less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
impl->mBase->onLastWeakRef(id);
if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
// this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
delete impl->mBase;//删除实际对象
}
}
}
再看Example对象的析构过程:
RefBase::~RefBase()
{
if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
// we never acquired a strong (and/or weak) reference on this object.
delete mRefs;
} else {
// life-time of this object is extended to WEAK or FOREVER, in
// which case weakref_impl doesn't out-live the object and we
// can free it now.
if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
// It's possible that the weak count is not 0 if the object
// re-acquired a weak reference in its destructor
if (mRefs->mWeak == 0) {
delete mRefs;
}
}
}
// for debugging purposes, clear this.
const_cast<weakref_impl*&>(mRefs) = NULL;
}
这样,所有的对象都已经删除掉。由上可知,强引用计数值为0时,会导致实际对象被删除;弱引用计数值为0时,会导致计数管理对象被删除。
PS:最近在看MediaService的代码,在BpBinder的构造函数中发现了这样一个函数调用;
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
{
ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);//拓展生命周期
IPCThreadState::self()->incWeakHandle(handle);
}
BpBinder是RefBase的子类,它在构造函数中调用了extendObjectLifetime()函数来拓展它的生命周期。我们把这个调用加进我们的示例中,并来分析下该调用的实际意义:
class Example : public RefBase {
extendObjectLifetime(OBJECT_LIFETIME_WEAK);//拓展生命周期
};
int main()
{
Example* exa = new Example;//1、创建Example指针对象
sp<Example> sP(exa);//2、创建sP
wp<Example> wP(exa);//3、创建wP
return 0;
}
从上面的分析可知,extendObjectLifetime()并不影响sp、wp的创建流程;所以还是需要从示例的析构过程着手。
extendObjectLifetime()的函数实现如下:
void RefBase::extendObjectLifetime(int32_t mode)
{
android_atomic_or(mode, &mRefs->mFlags);
}
它的参数值有这三种:
它只会设置Example的成员变量mFlags;由之前的介绍可知wp的析构函数会调用到:
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);//调试不管
const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为1;原值c=2
ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;//c=2,直接return
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlive the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong == INITIAL_STRONG_VALUE) {
// Special case: we never had a strong reference, so we need to
// destroy the object now.
delete impl->mBase;
} else {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
// less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
impl->mBase->onLastWeakRef(id);
if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
// this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
delete impl->mBase;
}
}
}
由于此时c=2,直接return掉;再看sp的析构调用,由之前介绍,会调用到:
void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);
const int32_t c = android_atomic_dec(&refs->mStrong);//强引用计数值减1,此时强引用计数为0;c = 1
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
if (c == 1) {
refs->mBase->onLastStrongRef(id);//函数体为空,无任何操作
if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {//我们设置了mFlags:OBJECT_LIFETIME_WEAK,不满足if条件;在强引用计数值为0时,我们没有删掉模板类型对象
delete this;
}
}
refs->decWeak(id);//此时弱引用计数为1,再对弱引用计数做一次原子减法
}
由于我们设置了mFlags的值,代码中的if条件并不满足,此时并不会删除掉原始对象,即模板类型实例。再看decWeak():
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);//调试不管
const int32_t c = android_atomic_dec(&impl->mWeak);//弱引用计数减1,经过此步骤后,弱引用计数值为0;原值c=1
ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;//c=1
//我们设置了mFlags:OBJECT_LIFETIME_WEAK,此时if条件并不满足,走else分支
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
// This is the regular lifetime case. The object is destroyed
// when the last strong reference goes away. Since weakref_impl
// outlive the object, it is not destroyed in the dtor, and
// we'll have to do it here.
if (impl->mStrong == INITIAL_STRONG_VALUE) {
// Special case: we never had a strong reference, so we need to
// destroy the object now.
delete impl->mBase;
} else {
// ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
// less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
impl->mBase->onLastWeakRef(id);
if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {//设置的mFlags满足此条件,所以会删除掉模板类型对象
// this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
// is gone, we can destroy the object.
delete impl->mBase;//删除模板类型对象,即原始对象
}
}
}
原始对象的删除会调用它的析构函数:
RefBase::~RefBase()
{
if (mRefs->mStrong == INITIAL_STRONG_VALUE) {//mStrong此时为0,不满足if条件
// we never acquired a strong (and/or weak) reference on this object.
delete mRefs;
} else {
// life-time of this object is extended to WEAK or FOREVER, in
// which case weakref_impl doesn't out-live the object and we
// can free it now.
//设置了mFlags后,此条件满足
if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
// It's possible that the weak count is not 0 if the object
// re-acquired a weak reference in its destructor
if (mRefs->mWeak == 0) {//弱引用计数经历过两次删除后,mWeak为0
delete mRefs;//删除计数管理对象
}
}
}
// for debugging purposes, clear this.
const_cast<weakref_impl*&>(mRefs) = NULL;//调试,置空指针
}
在析构函数中,引用计数管理对象被删除。由此,我们得出:当我们设置mFlags为OBJECT_LIFETIME_WEAK时,只有当强引用计数和弱引用计数值都为0时,模板类型对象和引用计数对象才会被删除;这明显和前面介绍的没有设置mFlags的过程不同。
二、类型提升
特殊地,我们可以将一个wp指针提升为sp指针,wp提供了一个成员函数来完成这种转换:
template<typename T>
sp<T> wp<T>::promote() const
{
sp<T> result;
if (m_ptr && m_refs->attemptIncStrong(&result)) {
result.set_pointer(m_ptr);
}
return result;
}
考虑这种使用场景,来看看它的内部处理流程:
class Example : public RefBase {};
int main()
{
Example* exa = new Example;
wp<Example> wP(exa);
sp<Example> sP = wP.promote();//类型提升
return 0;
}
当我们创建完wP时,此时强引用计数值应为0,弱引用计数值为1。看attemptIncStrong():
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
incWeak(id);//原子加法操作,若引用计数加1,此时过后,弱引用计数为2
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mStrong;//此时应为初始值0
ALOG_ASSERT(curCount >= 0,
"attemptIncStrong called on %p after underflow", this);
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
// we're in the easy/common case of promoting a weak-reference
// from an existing strong reference.
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
break;
}
// the strong count has changed on us, we need to re-assert our
// situation.
curCount = impl->mStrong;
}
if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
// we're now in the harder case of either:
// - there never was a strong reference on us
// - or, all strong references have been released
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {//走else分支
// this object has a "normal" life-time, i.e.: it gets destroyed
// when the last strong reference goes away
if (curCount <= 0) {
// the last strong-reference got released, the object cannot
// be revived.
decWeak(id);
return false;
}
// here, curCount == INITIAL_STRONG_VALUE, which means
// there never was a strong-reference, so we can try to
// promote this object; we need to do that atomically.
while (curCount > 0) {
if (android_atomic_cmpxchg(curCount, curCount + 1,
&impl->mStrong) == 0) {
break;
}
// the strong count has changed on us, we need to re-assert our
// situation (e.g.: another thread has inc/decStrong'ed us)
curCount = impl->mStrong;
}
if (curCount <= 0) {
// promote() failed, some other thread destroyed us in the
// meantime (i.e.: strong count reached zero).
decWeak(id);
return false;
}
} else {
// this object has an "extended" life-time, i.e.: it can be
// revived from a weak-reference only.
// Ask the object's implementation if it agrees to be revived
if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {//是否允许强引用加1,此场景下是允许的,返回TRUE
// it didn't so give-up.
decWeak(id);
return false;
}
// grab a strong-reference, which is always safe due to the
// extended life-time.
curCount = android_atomic_inc(&impl->mStrong);//强引用计数加1,开始处弱引用计数已经加1了
}
// If the strong reference count has already been incremented by
// someone else, the implementor of onIncStrongAttempted() is holding
// an unneeded reference. So call onLastStrongRef() here to remove it.
// (No, this is not pretty.) Note that we MUST NOT do this if we
// are in fact acquiring the first reference.
if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
impl->mBase->onLastStrongRef(id);//无任何操作
}
}
impl->addStrongRef(id);
#if PRINT_REFS
ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount);
#endif
// now we need to fix-up the count if it was INITIAL_STRONG_VALUE
// this must be done safely, i.e.: handle the case where several threads
// were here in attemptIncStrong().
curCount = impl->mStrong;
while (curCount >= INITIAL_STRONG_VALUE) {
ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
"attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
this);
if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong) == 0) {
break;
}
// the strong-count changed on us, we need to re-assert the situation,
// for e.g.: it's possible the fix-up happened in another thread.
curCount = impl->mStrong;
}
return true;
}
代码中给该对象的强弱引用计数值都自加了1,此时就对象的强引用计数值为1,弱引用计数值为2了。
template<typename T>
void sp<T>::set_pointer(T* ptr) {
m_ptr = ptr;
}
再将实际对象指针保存到sp中。
PS:在Android native代码中,一般的对象指针都已经被sp、wp等代替了,用了它们,我们无需手动去回收指针对象,这样极大地提升了程序的稳定性。而在大多数的native程序中,sp、wp都只是一个代替普通指针的工具,我们能了解它的原理更好,不了解的话,就把它们当中普通指针来看待就行了。
我觉得这些内容中最要注意的一点就是sp第一次构建完成后,会调用实际对象的onFirstRef()函数;在有些场景中,这一点会很容易被忽略,但确实有一些程序会在onFirstRef()方法中做一些初始化操作;如果不记住这点,碰到这种情况,我们看代码时,可能会觉得有一些困惑,而这个困惑恰恰是可以避免的。