BBinder对象 } }// 如果此时还有其他指向该目标对象的sp指针存在的话,就不会删除目标对象 refs->removeWeakRef(id); refs->decWeak(id); /* 删除新建目标对象sp指针时在mWeakRefs链表上增加的两个ref_entry结构体 */ } /*********************************注释3*********************************/ void removeStrongRef(const void* id) { if (!mRetain) // mRetain 初始化成 flase removeRef(&mStrongRefs, id); /* 删除mStrongRefs链表中对应id的ref_entry一项 */ /* 也就是取消了该sp对象和目标对象的联系 */ else addRef(&mStrongRefs, id, -mStrong); } void removeRef(ref_entry** refs, const void* id) { if (mTrackEnabled) { AutoMutex _l(mMutex); ref_entry* ref = *refs; while (ref != NULL) { if (ref->id == id) { *refs = ref->next; delete ref; return; } refs = &ref->next; ref = *refs; } } } /*********************************注释3*********************************/ delete BB_wp_ptr; 这是删除目标对象的一个wp指针,会调用wp的析构函数: template wp::~wp() { if (m_ptr) m_refs->decWeak(this); } 调用weakref_type类的decWeak()函数,如下: void RefBase::weakref_type::decWeak(const void* id) { weakref_impl* const impl = static_cast(this); impl->removeWeakRef(id);// 移除weakref_impl对象mWeakRefs链表中对应id的ref_entry结构体 const int32_t c = android_atomic_dec(&impl->mWeak);// 引用计数减1 LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); if (c != 1) return; // c == 1, 说明这是系统中存在的指向目标对象的最后一个wp指针 if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) { if (impl->mStrong == INITIAL_STRONG_VALUE) delete impl->mBase; // delete impl; 是不是应该加上这么一句,防止用户新建了wp后,不用,马上又删除的情况呢? /* 当目标对象的最后一个wp被析构时,如果目标对象还没有建立任何一个sp,那么目标对象被删除 */ else { delete impl; /* 当目标对象的最后一个wp被析构时,但此时和目标对象相关的sp全部被析构,那么impl->mStrong = 0 在最后一个sp被析构的时候,目标对象也被释放,所以此时只需要释放weakref_impl对象即可 */ } } else { impl->mBase->onLastWeakRef(id); if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) { delete impl->mBase; } } }
四、wp升级为sp的过程 wp的定义包含了:sp promote() const; template sp wp::promote() const { return sp(m_ptr, m_refs); } wp,sp互为友元类,这里promote就是以友元身份调用了sp类的构造函数: sp(T* p, weakref_type* refs); template sp::sp(T* p, weakref_type* refs) : m_ptr((p && refs->attemptIncStrong(this)) p : 0) { } 这里如果升级成功,那么将会产生一个sp对象指向目标对象,原来的wp仍然存在。 如果升级不成功,返回NULL 看看关键函数refs->attemptIncStrong(this)
bool RefBase::weakref_type::attemptIncStrong(const void* id) { incWeak(id); weakref_impl* const impl = static_cast(this); int32_t curCount = impl->mStrong; LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", this); while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { break; } curCount = impl->mStrong; }// 系统中还有其他sp指向目标对象的情况 if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { bool allow; if (curCount == INITIAL_STRONG_ |