Android中wp promote为sp流程
2015-09-17 13:54
393 查看
几个相关class的定义位置:
system/core$ vim include/utils/RefBase.h 其中定义了class wp
system/core/libutils/RefBase.cpp 其中定义了class RefBase::weakref_impl
system/core$ vim include/utils/StrongPointer.h 其中定义了class sp
以以下代码运行为例:
链接:http://blog.csdn.net/mfbao01/article/details/6255655
第一步:调用wp构造方法
system/core/include/utils/RefBase.h
上一步调了实例对像WPTest类的createWeak方法,但其中没有定义。对于用智能指针的类,都要继承类RefBase
此方法调的就是RefBase中的方法
system/core/libutils/RefBase.cpp
所以,m_refs = mRefs
mRefs是在RefBase构造方法中始初化的,RefBase构造方法为:
system/core/libutils/RefBase.cpp
---[2]--- 下一步增加引用计数值,android_atomic_inc就是将impl中的mWeak变量数值加1,mWeak变量就是管理wp对象的引用计数
第二步:promote成强引用指针
system/core/include/utils/RefBase.h
这里就申明了一个强引用sp类对象result,m_refs上面说了是weakref_type指针
impl->mFlags为0并没有设置OBJECT_LIFETIME_WEAK值
android_atomic_cmpxchg(curCount, curCount + 1, &impl->mStrong)中将impl->mStrong的值设为了curCount+1
之后再通过
android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong)将curCount-INITIAL_STRONG_VALUE附给impl->mStrong, 实现强指针的计数。
$(".MathJax").remove();
system/core$ vim include/utils/RefBase.h 其中定义了class wp
system/core/libutils/RefBase.cpp 其中定义了class RefBase::weakref_impl
system/core$ vim include/utils/StrongPointer.h 其中定义了class sp
以以下代码运行为例:
链接:http://blog.csdn.net/mfbao01/article/details/6255655
class WPTest : public RefBase { public: WPTest(){ LOGD("WPTest constructor"); } virtual ~WPTest() { LOGD("WPTest destructor"); } virtual void onFirstRef() { LOGD("first weak ptr ref callback"); } virtual void onLastStrongRef(const void* id) { LOGD("last strong ptr ref callback"); } virtual void onLastWeakRef(const void* id) { LOGD("last weak ptr ref callback"); } }; int main() { WPTest *T = new WPTest(); { wp<WPTest> weakp(T); { LOGD("promote to strong ptr.../n"); sp<WPTest> strongp = weakp.promote(); LOGD("strong ptr's lifetime is just about to finish .../n"); } LOGD("weak ptr's lifetime is just about to finish .../n"); } LOGD("weak ptr is out of scope./n"); return 0; }
第一步:调用wp构造方法
system/core/include/utils/RefBase.h
template<typename T> template<typename U> wp<T>::wp(U* other) : m_ptr(other) { if (other) m_refs = other->createWeak(this); }m_refs为weakref_type类型的指针
上一步调了实例对像WPTest类的createWeak方法,但其中没有定义。对于用智能指针的类,都要继承类RefBase
此方法调的就是RefBase中的方法
system/core/libutils/RefBase.cpp
RefBase::weakref_type* RefBase::createWeak(const void* id) const { mRefs->incWeak(id); //id为上面wp指针 return mRefs; }
所以,m_refs = mRefs
mRefs是在RefBase构造方法中始初化的,RefBase构造方法为:
RefBase::RefBase() : mRefs(new weakref_impl(this)) { }所以mRefs->incWeak就是调用了weakref_impl中的方法,weakref_impl定义在
system/core/libutils/RefBase.cpp
class RefBase::weakref_impl : public RefBase::weakref_typeincWeak方法的实现在类weakref_type中
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); ---[2]--- ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); }---[1]--- 先看看impl->addWeakRef(id)其中id是上面wp的this指针,也就是类wp的地址
void addWeakRef(const void* id) { addRef(&mWeakRefs, id, mWeak); }其中mWeakRefs为ref_entry结构体的指针,值为初始值NULL; mWeak为对像的引用计数值,为初始值0
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; } }以上代码就是生成一个新的ref_entry结构用来存放对象的弱引用计数和wp的地址,新结构体放在最上面,也就是当前引用数和对应wp对象的一个记录信息
---[2]--- 下一步增加引用计数值,android_atomic_inc就是将impl中的mWeak变量数值加1,mWeak变量就是管理wp对象的引用计数
第二步:promote成强引用指针
system/core/include/utils/RefBase.h
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; }
这里就申明了一个强引用sp类对象result,m_refs上面说了是weakref_type指针
bool RefBase::weakref_type::attemptIncStrong(const void* id) { incWeak(id); //其中id为新创建sp类result的地址,它会新建个结构体保存当前引用计数值和sp地址加入链表,并将弱引用计数加1 weakref_impl* const impl = static_cast<weakref_impl*>(this); int32_t 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) { // 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; } ...... 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; }impl->mStrong的初始值为INITIAL_STRONG_VALUE
#define INITIAL_STRONG_VALUE (1<<28)
impl->mFlags为0并没有设置OBJECT_LIFETIME_WEAK值
android_atomic_cmpxchg(curCount, curCount + 1, &impl->mStrong)中将impl->mStrong的值设为了curCount+1
之后再通过
android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
&impl->mStrong)将curCount-INITIAL_STRONG_VALUE附给impl->mStrong, 实现强指针的计数。
$(".MathJax").remove();
相关文章推荐
- Android多线程任务优化1:探讨AsyncTask的缺陷
- 关于安卓开发选择android 4.2.2(API 17)应用无法打开的解决办法
- 【Android】Log优雅的注释(github开源项目)
- Android 动态创建Drawable selector
- ListView+checkBox删除需求实现以及注意事项
- Android 音效 SoundPool
- 【Android】别话 AsyncTask
- Android 混淆备忘
- android5.0以上版本的状态栏透明
- android NDK 笔记
- 【Android】时区、时制、电量、内存信息
- 【Android】轮询的若干问题 Timer, TimerTask;Timer 的缺陷,ScheduledThreadPoolExecutor
- android开发笔记,杂
- 【Android】DownloadManager的使用
- Android本地数据库升级
- Android Activity和Fragment传递数据
- 【Android】FileInputStream
- android数据的四种存储方式
- Android 屏幕适配问题
- Android 反编译工具备忘