`
zzu_007
  • 浏览: 23777 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android源码之智能指针

阅读更多
No.1 智能指针的设计
    智能指针是通过引用技术来控制对象的生成和销毁的。我们知道在才C++中对象的生成和销毁会自动调用对象的构造函数和析构函数,所以智能指针的大部分逻辑都集中在构造函数和析构函数中,这也是我们分析的重点。
    因为Android的职能指针是通过引用计数的方法来实现的。所以在设计中会涉及到两个层次。第一层是定义控制引用计数的对象,我们称之为引用计数控制类。第二层才是对真实对象的访问,可以把这个对象看作是对真实对象的包裹。所以我们把这个类称之为包裹类。
    这样职能指针会自动帮你控制对象的创建和销毁了。
    在Android系统里,主要存在三种职能指针轻量级指针(LightRefBase),强指针(sp), 弱指针(wp).

这部分涉及的代码裂变如下:
(1) RefBase.h 位于:/frameworks/native/include/RefBase.h
(2) RefBash.cpp 位于: /frameworks/native/libs/RefBase.cpp
(3) StrongPointer.h 位于:/frameworks/native/include/StrongPointer.h

接下来我们就从简单的入手,分析轻量级指针的实现。
1 轻量级指针
我们在前面说过,智能指针的设计会涉及到两方面。我们就先看看引用计数控制类。
(1) LightRefBase类,定义在RefBase.h。代码如下:
template <class T>
class LightRefBase
{
public:
//默认构造函数,将mCount设置为0,表示还没有指向该对象的指针
inline LightRefBase() : mCount(0) { }
//原子增加成员变量mCount+1,表示增加了指向该对象的指针的个数
inline void incStrong(const void* id) const {
android_atomic_inc(&mCount);
}
//原子减少成员变量mCount-1,表示减少了指向该对象的指针的个数
//如果减1之前,mCount的值为1,说明当前只有一个指针指向该对象,这时候就可以删除掉该对象,即调用该对象的析构函数
inline void decStrong(const void* id) const {
if (android_atomic_dec(&mCount) == 1) {
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
// 返回当前指向该对象的指针的个数
inline int32_t getStrongCount() const {
return mCount;
}

typedef LightRefBase<T> basetype;

protected:
//析构函数
inline ~LightRefBase() { }

private:
//这是干什么用的?我还不知道
friend class ReferenceMover;
inline static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster) { }

private:
//记录指向该对象的指针的个数
mutable volatile int32_t mCount;
};
LightRefBase实现的很简单。就是利用一个int值表示当前指向该对象的指针的个数。前面说过,计数控制类是配合包裹类来完成智能指针的功能的。
细心的读者可以发现,LightRefBase其实是个模版类。
那轻量级的包裹类是怎么实现的呢?其实Android类没有单独实现轻量级类的包裹类。轻量级类的包裹类是SP。其实这个SP类也是强指针的包裹类。所以我们以后在分析它的实现。

2 强指针
强指针就不能简单的用一个int的成员变量来控制指针对象的生命周期了,所以在强指针的实现中定义了更复杂的计数控制类,这个类就是RefBase类。
强指针的计数控制类如下:
(1) RefBase类,定义在RefBase.h中
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;

//weakref_type相当于一个接口,定义了操作计数的函数,之后我们会看到RefBase类的成员变量mRefs其实就是这个类的一个实现类
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 ReferenceMover;
static void moveReferences(void* d, void const* s, size_t n, const ReferenceConverterBase& caster);

private:
friend class weakref_type;
class weakref_impl;
//拷贝和赋值构造函数,定义成私有,why??
RefBase(const RefBase& o);
RefBase& operator=(const RefBase& o);
//控制计数的类,相当与LightRefBase中的mCount
weakref_impl* const mRefs;
};
接下来我们看一下这个类的实现
RefBase::RefBase()
: mRefs(new weakref_impl(this))
{
}
RefBase的构造函数,也就是计数控制类本身的构造函数。这个函数就是简单的将成员变量mRefs初始化为一个指向weakref_impl的指针。weakref_impl类其实是RefBase的内部类weakref_type类的一个实现类。

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;
}
RefBase类的析构函数。因为我们在使用Android系统提供的职能指针时,一般是继承自RefBase类,表示这个正在定义的类具有了引用计数的能力,只有这样,才能配合强智能指针和弱职能指针的包裹类,来实现自动维护对象的创建和销毁的功能。

void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
//增弱引用计数
refs->incWeak(id);

//调试用的
refs->addStrongRef(id);
//强引用计数加1
const int32_t c = android_atomic_inc(&refs->mStrong);

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

//如果强引用技术在加1前的值不是初始值的话,则说明当前有多个指针指向该对象,直接返回
if (c != INITIAL_STRONG_VALUE)  {
return;
}

//将强引用计数的值减去初始值,也就是将强引用计数的值设置成1了
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
//因为是首次引用了该对象,所以调用宿主指针的onFirstRef函数,相当于通知了宿主指针。可以在该函数里实现一些首次引用的逻辑
refs->mBase->onFirstRef();
}
这个函数增加强引用计数。从实现上我们可以看出,增加强引用计数的时候,是肯定会增加弱引用计数的。

void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
//调试用的
refs->removeStrongRef(id);
//强引用计数减1
const int32_t c = android_atomic_dec(&refs->mStrong);

#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);

//如果减1之前,强引用计数为1。说明当前只有一个指针指向该对象。
if (c == 1) {
//所以调用宿主指针的onLastStrongRef函数。通知宿主指针当前是最后一个指针指向该对象。
refs->mBase->onLastStrongRef(id);
//如果当前对象的生命周期是受强引用控制的,就在此删除当前对象
if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
delete this;
}
}

//减少弱引用计数的值
refs->decWeak(id);
}
这个函数减少强引用计数。从中我们也可以看出,减少强引用计数的同时,会减少弱引用计数。

void RefBase::forceIncStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
//增弱引用计数
refs->incWeak(id);
//调试用的
refs->addStrongRef(id);
//强引用计数加1
const int32_t c = android_atomic_inc(&refs->mStrong);

ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
   refs);
#if PRINT_REFS
ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
#endif

//判断是首次引用还是有已经有多个引用
switch (c) {
case INITIAL_STRONG_VALUE:
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
// fall through...
//注意,这里没有break;
case 0:
refs->mBase->onFirstRef();
}
}
这个函数逻辑上和incStrong函数是一样的。

int32_t RefBase::getStrongCount() const
{
return mRefs->mStrong;
}
这个函数只是简单的返回强引用计数的值。从源码注释中可以知道,这个函数只是调试用的。

RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id);
return mRefs;
}
这个函数相当于获得了一个引用控制类。在返回当前对象的成员变量mRefs之前,增加了弱引用计数。

RefBase::weakref_type* RefBase::getWeakRefs() const
{
return mRefs;
}
这个函数只是简单的返回了当前对象的成员变量mRefs。并没有增加弱引用计数。

void RefBase::extendObjectLifetime(int32_t mode)
{
//原子的设置成员变量mRefs的mFlags
android_atomic_or(mode, &mRefs->mFlags);
}
这个函数设置对象的生命周期的控制模式。mode的取值如下enum所定义
enum {
OBJECT_LIFETIME_STRONG  = 0x0000,
OBJECT_LIFETIME_WEAK    = 0x0001,
OBJECT_LIFETIME_MASK    = 0x0001
};
至此我们分析了RefBase类的实现,从中我们可以看出。RefBase的函数都是通过mRefs成员变量来操纵引用计数的。所以接下来我们就分析weakref_impl类的实现。
(2) weakref_impl类,定义和实现在RefBase.cpp中。
class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
volatile int32_t    mStrong; /*强引用计数成员变量*/
volatile int32_t    mWeak; /*弱引用计数成员变量*/
RefBase* const      mBase; /*指向宿主对象*/
volatile int32_t    mFlags; /*控制对象生命周期模式的标示符*/

#if !DEBUG_REFS

//构造函数
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)
, mWeak(0)
, mBase(base)
, mFlags(0)
{
}

//和调试有关的函数,我们可以看出,在发行版本中,这些函数都是空函数
void addStrongRef(const void* /*id*/) { }
void removeStrongRef(const void* /*id*/) { }
void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
void addWeakRef(const void* /*id*/) { }
void removeWeakRef(const void* /*id*/) { }
void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
void printRefs() const { }
void trackMe(bool, bool) { }

#else

weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)
, mWeak(0)
, mBase(base)
, mFlags(0)
, mStrongRefs(NULL)
, mWeakRefs(NULL)
, mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
, mRetain(false)
{
}

~weakref_impl()
{
bool dumpStack = false;
if (!mRetain && mStrongRefs != NULL) {
dumpStack = true;
#if DEBUG_REFS_FATAL_SANITY_CHECKS
LOG_ALWAYS_FATAL("Strong references remain!");
#else
ALOGE("Strong references remain:");
#endif
ref_entry* refs = mStrongRefs;
while (refs) {
char inc = refs->ref >= 0 ? '+' : '-';
ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
#if DEBUG_REFS_CALLSTACK_ENABLED
refs->stack.dump();
#endif
refs = refs->next;
}
}

if (!mRetain && mWeakRefs != NULL) {
dumpStack = true;
#if DEBUG_REFS_FATAL_SANITY_CHECKS
LOG_ALWAYS_FATAL("Weak references remain:");
#else
ALOGE("Weak references remain!");
#endif
ref_entry* refs = mWeakRefs;
while (refs) {
char inc = refs->ref >= 0 ? '+' : '-';
ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
#if DEBUG_REFS_CALLSTACK_ENABLED
refs->stack.dump();
#endif
refs = refs->next;
}
}
if (dumpStack) {
ALOGE("above errors at:");
CallStack stack;
stack.update();
stack.dump();
}
}

void addStrongRef(const void* id) {
//ALOGD_IF(mTrackEnabled,
//        "addStrongRef: RefBase=%p, id=%p", mBase, id);
addRef(&mStrongRefs, id, mStrong);
}

void removeStrongRef(const void* id) {
//ALOGD_IF(mTrackEnabled,
//        "removeStrongRef: RefBase=%p, id=%p", mBase, id);
if (!mRetain) {
removeRef(&mStrongRefs, id);
} else {
addRef(&mStrongRefs, id, -mStrong);
}
}

void renameStrongRefId(const void* old_id, const void* new_id) {
//ALOGD_IF(mTrackEnabled,
//        "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
//        mBase, old_id, new_id);
renameRefsId(mStrongRefs, old_id, new_id);
}

void addWeakRef(const void* id) {
addRef(&mWeakRefs, id, mWeak);
}

void removeWeakRef(const void* id) {
if (!mRetain) {
removeRef(&mWeakRefs, id);
} else {
addRef(&mWeakRefs, id, -mWeak);
}
}

void renameWeakRefId(const void* old_id, const void* new_id) {
renameRefsId(mWeakRefs, old_id, new_id);
}

void trackMe(bool track, bool retain)
{
mTrackEnabled = track;
mRetain = retain;
}

void printRefs() const
{
String8 text;

{
Mutex::Autolock _l(mMutex);
char buf[128];
sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
text.append(buf);
printRefsLocked(&text, mStrongRefs);
sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
text.append(buf);
printRefsLocked(&text, mWeakRefs);
}

{
char name[100];
snprintf(name, 100, "/data/%p.stack", this);
int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
if (rc >= 0) {
write(rc, text.string(), text.length());
close(rc);
ALOGD("STACK TRACE for %p saved in %s", this, name);
}
else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
  name, strerror(errno));
}
}

private:
struct ref_entry
{
ref_entry* next;
const void* id;
#if DEBUG_REFS_CALLSTACK_ENABLED
CallStack stack;
#endif
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;
// Reference count at the time of the snapshot, but before the
// update.  Positive value means we increment, negative--we
// decrement the reference count.
ref->ref = mRef;
ref->id = id;
#if DEBUG_REFS_CALLSTACK_ENABLED
ref->stack.update(2);
#endif
ref->next = *refs;
*refs = ref;
}
}

void removeRef(ref_entry** refs, const void* id)
{
if (mTrackEnabled) {
AutoMutex _l(mMutex);

ref_entry* const head = *refs;
ref_entry* ref = head;
while (ref != NULL) {
if (ref->id == id) {
*refs = ref->next;
delete ref;
return;
}
refs = &ref->next;
ref = *refs;
}

#if DEBUG_REFS_FATAL_SANITY_CHECKS
LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
"(weakref_type %p) that doesn't exist!",
id, mBase, this);
#endif

ALOGE("RefBase: removing id %p on RefBase %p"
"(weakref_type %p) that doesn't exist!",
id, mBase, this);

ref = head;
while (ref) {
char inc = ref->ref >= 0 ? '+' : '-';
ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
ref = ref->next;
}

CallStack stack;
stack.update();
stack.dump();
}
}

void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
{
if (mTrackEnabled) {
AutoMutex _l(mMutex);
ref_entry* ref = r;
while (ref != NULL) {
if (ref->id == old_id) {
ref->id = new_id;
}
ref = ref->next;
}
}
}

void printRefsLocked(String8* out, const ref_entry* refs) const
{
char buf[128];
while (refs) {
char inc = refs->ref >= 0 ? '+' : '-';
sprintf(buf, "\t%c ID %p (ref %d):\n",
inc, refs->id, refs->ref);
out->append(buf);
#if DEBUG_REFS_CALLSTACK_ENABLED
out->append(refs->stack.toString("\t\t"));
#else
out->append("\t\t(call stacks disabled)");
#endif
refs = refs->next;
}
}

mutable Mutex mMutex;
ref_entry* mStrongRefs;
ref_entry* mWeakRefs;

bool mTrackEnabled;
// Collect stack traces on addref and removeref, instead of deleting the stack references
// on removeref that match the address ones.
bool mRetain;

#endif
};
weakref_impl继承自RefBase的内部类weakref_type,貌似实现了很多的逻辑。其实不然,我们可以看到在代码从#if !DEBUG_REFS 到#else之间的部分定义的函数除了构造函数都是空函数。从#else到类定义结尾的#endif之间的函数都是有实现的函数。而这些函数都是和调试有关的函数。所以在这里是利用DEBUG_REFS宏来控制是否编译调试相关的代码的。在发行版中,会想DEBUG_REFS定义成0,这样所有的调试代码的实现都为空了。
所以在这里我们只关心构造函数。其他的函数实现我们可以忽略。
weakref_impl的实现很简单。只是初始化了成员变量。其中把mStrong初始化为INITIAL_STRONG_VALUE,而在RefBase.cpp存在宏:define INITIAL_STRONG_VALUE (1<<28),这样就把mStrong初始化为一个常量。将mWeak初始化为0。将mBase指向宿主对象base。将mFlags初始化为0,而0等于OBJECT_LIFETIME_STRONG  = 0x0000,也就是智能指针默认是由强引用计数控制生命周期的。
接下来我们看一看weakref_impl的成员函数的实现。
RefBase* RefBase::weakref_type::refBase() const
{
return static_cast<const weakref_impl*>(this)->mBase;
}
这个函数得到指向宿主对象的指针。

void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
//调试用
impl->addWeakRef(id);
//将弱引用计数值加1
const int32_t c = android_atomic_inc(&impl->mWeak);

ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
这个函数增加弱引用计数。可以看出,增加弱引用计数值,并没有增加强引用计数值。

void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
//调试用
impl->removeWeakRef(id);
//将弱引用计数值减1
const int32_t c = android_atomic_dec(&impl->mWeak);

ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);

//之前的弱引用计数不为1,表示有多个指针指向当前对象的弱指针
if (c != 1) return;

//之前的弱引用计数为1,表示之前只有一个指针指向当前对象的弱指针
//如果对象的生命周期受强引用计数的控制
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;
}
}
}
这个函数减少弱引用计数的值。

bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
//增加弱引用计数
incWeak(id);

weakref_impl* const impl = static_cast<weakref_impl*>(this);

//得到当前的强引用计数的值
int32_t curCount = impl->mStrong;

ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
   this);
  
//curCount > 0 && curCount != INITIAL_STRONG_VALUE 表明当前有多个强指针指向该对象,这时候只要简单的增加强引用计数的值就可以了
//为什么用while?为什么用android_atomic_cmpxchg?后面会分析。
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
break;
}
curCount = impl->mStrong;
}

//curCount <= 0 || curCount == INITIAL_STRONG_VALUE说明此时目标对象没有被任何强指针引用,所以要分两种情况分析
if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
bool allow;
//curCount == INITIAL_STRONG_VALUE说明此目标对象还从未被强指针引用过
if (curCount == INITIAL_STRONG_VALUE) {
// Attempting to acquire first strong reference...  this is allowed
// if the object does NOT have a longer lifetime (meaning the
// implementation doesn't need to see this), or if the implementation
// allows it to happen.
allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
} else { //curCount <= 0, 说明此对象之前肯定被强指针引用过
// Attempting to revive the object...  this is allowed
// if the object DOES have a longer lifetime (so we can safely
// call the object with only a weak ref) and the implementation
// allows it to happen.
allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
}

//不允许增加强引用计数
if (!allow) {
//减少弱引用计数的值,因为一进入函数就增加了弱引用计数
decWeak(id);
return false;
}

//增加强引用计数
curCount = android_atomic_inc(&impl->mStrong);

// 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

//通知宿主对象
if (curCount == INITIAL_STRONG_VALUE) {
android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);
impl->mBase->onFirstRef();
}

return true;
}
这个函数试图增加强引用计数的值,但是有可能会失败,失败的原因可能是因为目标对象已经被delete掉了,或者是其它的原因。

bool RefBase::weakref_type::attemptIncWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);

int32_t curCount = impl->mWeak;
ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
   this);
while (curCount > 0) {
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
break;
}
curCount = impl->mWeak;
}

if (curCount > 0) {
impl->addWeakRef(id);
}

return curCount > 0;
}






分享到:
评论

相关推荐

    anroid智能指针(wp,sp)学习总结

    智能指针sp和wp在android c++源码中使用非常频繁,例如IBinder机制,但是它比c++中普通的智能指针要复杂很多,相信不少android学习者如果c++基础不是很扎实的,看起来会比较吃力和枯燥。本人在android 4.2.2源码基础...

    Android应用程序框架——智能指针 系列文章源代码

    在Android应用程序开发中,智能指针是用于管理内存的重要工具,尤其是在C++ Native层的编程中。本系列文章源代码主要探讨了如何在Android环境中利用智能指针来优化内存管理和防止内存泄漏。智能指针是一种自动管理...

    android应用源码---浏览器源码(AndroidChromium).rar

    9. **内存管理**:理解Chromium如何高效地分配和释放内存,以及如何利用内存池和智能指针来减少内存泄漏,对Android应用开发者来说非常有价值。 10. **UI设计**:Chromium的UI设计遵循Material Design指南,源码中...

    Android股票查询源码

    Android是一个开源的操作系统,广泛应用于智能手机和平板电脑。开发Android应用需要用到Java或Kotlin语言,以及Android Studio作为集成开发环境(IDE)。在这个项目中,源码可能包括了用于获取实时股票数据、处理...

    安卓Android源码——指南针安卓端源码.zip

    "安卓Android源码——指南针安卓端源码.zip" 是一个与安卓应用开发相关的资源,其中包含了实现指南针功能的Android应用程序的源代码。这通常意味着源码将涵盖如何在Android平台上利用传感器数据(如磁力传感器)来...

    Android C++高级编程-使用NDK_源码

    源码可能包含C++11、C++14或C++17的新特性,如智能指针、lambda表达式、类型推断等。 6. **第三方库集成**:可能有示例展示了如何在Android项目中集成和使用如SDL、OpenCV、Box2D等C++库。 7. **错误处理和调试**...

    Android应用源码之代码调用C++代码和C++代码调用代码.rar

    Android NDK支持C++11及以上版本,这使得开发者可以利用C++的新特性,如智能指针、lambda表达式和右值引用等,提高代码的可读性和效率。 6. **JNI函数调用** 调用C++代码时,Java代码会通过JNI函数调用C++中的...

    Android应用源码之指南针安卓端源码-IT计算机-毕业设计.zip

    这篇文档将深入解析《Android应用源码之指南针安卓端源码》这一项目,它是一个Android应用程序的源代码实现,适用于毕业设计学习。通过分析这个项目,你可以掌握Android开发的基本概念,了解移动应用的设计和实现...

    无线鼠标 android端 源码

    无线鼠标在 Android 设备上的实现是移动设备功能扩展的一个典型示例,它允许用户将智能手机或平板电脑转化为无线鼠标,方便地控制计算机。本文将深入探讨如何利用 Android 开发环境和 Java 语言构建这样的应用,主要...

    Android应用源码之Android 4.0下指南针开发源码,可在Nexus 4上完美运行-IT计算机-毕业设计.zip

    - Nexus 4是一款运行Android系统的智能手机,表明源码经过了实际设备的测试和验证。 2. **AndroidManifest.xml**: - 应用的配置文件,定义了应用的组件、权限、最低API级别和其他必要信息。 - 可能包含对使用...

    安卓Android源码——mouseovertest.rar

    在安卓(Android)平台上,开发者经常需要处理用户与应用程序的各种交互,其中之一就是鼠标悬停事件。"mouseovertest.rar"这个压缩包可能包含了一个示例项目,用于演示如何在Android应用中实现对鼠标悬停事件的检测...

    安卓Android源码——[安卓开源]MIUI指南针.zip

    标题"安卓Android源码——[安卓开源]MIUI指南针.zip"指出,这是一份关于安卓操作系统的源代码,具体是针对MIUI系统中的指南针应用。MIUI是由中国小米公司开发的深度定制Android系统,以其丰富的功能和独特的设计风格...

    android Mi-Compass源码.rar

    Android是一个开源的操作系统,主要应用于智能手机和平板电脑。它的应用程序主要采用Java语言编写,并通过Android SDK进行开发。Mi-Compass作为一款Android应用,遵循了Android的开发规范和生命周期。 2. **传感器...

    毕业设计源码之基于Android指南针作业.zip

    【标题】"毕业设计源码之基于Android指南针作业.zip" 涉及的主要知识点是Android应用程序开发,尤其是实现一个指南针应用。Android是Google主导的开源移动操作系统,主要用于智能手机和平板电脑。在这个毕业设计中,...

    Android 英语单词记忆程序源码.zip

    - 使用智能指针(如Java的弱引用或Android的Lifecycle-aware components)避免内存泄漏。图片加载库如Glide或Picasso可以优化内存使用,防止因大图加载导致的OOM(OutOfMemory)错误。 6. **网络通信**: - 如果...

    Android C++高级编程:使用NDK 源码

    - **Chapter 10 Source Code.zip**:可能讨论了C++11或更高版本的新特性,如Lambda表达式、右值引用和智能指针,这些在现代C++开发中非常重要。 - **Chapter 13 Source Code.zip**:可能涉及了Android的多媒体处理...

    android连接SQLite数据库源码.zip源码资源下载

    在Android开发中,SQLite是一个非常重要的组成部分,它是一个轻量级的、开源的、自包含的、关系型数据库系统,特别适合嵌入式设备使用,如智能手机和平板电脑。本资源"android连接SQLite数据库源码.zip"提供了一个...

    Android-该自定义控件是一个可以滑动改变温度值的表盘控件

    通过ValueAnimator或者ObjectAnimator,可以轻松地创建出在用户滑动时指针随之流畅变化的效果。 此外,我们还需要考虑控件的触摸反馈,比如在用户滑动时显示触控指示器,以及在松开手指时播放完成动画。这些可以...

    Android多功能拨号盘源码.zip

    《Android多功能拨号盘源码解析》 在移动操作系统领域,Android以其开源、灵活的特点深受开发者喜爱。在Android应用开发中,拨号盘是不可或缺的一部分,它为用户提供了一个直观、便捷的方式进行电话拨打。本篇将...

    Android系统源代码情景分析-罗升阳-源码

    第3章 智能指针 3.1 轻量级指针 3.1.1 实现原理分析 3.1.2 应用实例分析 3.2 强指针和弱指针 3.2.1 强指针的实现原理分析 3.2.2 弱指针的实现原理分析 3.2.3 应用实例分析 第2篇 Android专用驱动系统 第4章...

Global site tag (gtag.js) - Google Analytics