Android 强弱引用
软件:Source Insight 4.0、starUml
代码目录:
system/core/include/utils/RefBase.h
system/core/include/utils/StrongPointer.h
system/core/libutils/RefBase.cpp
一、简介
从media服务的main函数入口中,可以发现
sp<ProcessState> proc(ProcessState::self());
sp其实就是强指针或强引用(strong pointer),与 sp 对应的是 wp,也就是弱指针或弱引用(weak pointer),Android Native 层(C++)中大量使用了sp/wp,了解sp/wp的源码及使用对理解Android Native层是很有帮助的。
智能指针最大的作用就是自动销毁对象。有这么一个场景,对象 A 和 对象 B 互相引用,系统无法回收这两个对象,任意回收其中一个对象,都会发现被另外一个对象引用,导致“死锁”无法回收,针对这种情况,可以使用强弱指针,对A对象使用强指针计数,对B对象使用弱指针计数,只要强指针计数为0,不管弱引用计数是否为0,都可以回收这个对象。一个对象只有弱指针引用时,必须升级为强指针,才能使用这个对象。
二、sp 源码分析
sp 强指针就是一个模板类,有点类似于Java的泛型,先看下 sp 的头文件 StrongPointer.h
:
template<typename T>
class sp {
public:
inline sp() : m_ptr(0) {
}
sp(T* other); // 方式1
sp(const sp<T>& other); // 方式2
sp(sp<T>&& other); // 方式3
template<typename U> sp(U* other); // NOLINT(implicit)
template<typename U> sp(const sp<U>& other); // NOLINT(implicit)
template<typename U> sp(sp<U>&& other); // NOLINT(implicit)
~sp();
// Assignment
sp& operator = (T* other); // 方式4
sp& operator = (const sp<T>& other); // 方式5
sp& operator = (sp<T>&& other); // 方式6
template<typename U> sp& operator = (const sp<U>& other);
template<typename U> sp& operator = (sp<U>&& other);
template<typename U> sp& operator = (U* other);
//! Special optimization for use by ProcessState (and nobody else).
void force_set(T* other);
// Reset
void clear();
// Accessors
inline T& operator* () const {
return *m_ptr; }
inline T* operator-> () const {
return m_ptr; }
inline T* get() const {
return m_ptr; }
inline explicit operator bool () const {
return m_ptr != nullptr; }
// Operators
COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};
2.1 sp 构造函数
【StrongPointer.h】
sp 初始化的方式有6种:
sp(T* other); // 方式1
sp(const sp<T>& other); // 方式2
sp(sp<T>&& other); // 方式3
sp& operator = (T* other); // 方式4
sp& operator = (const sp<T>& other); // 方式5
sp& operator = (sp<T>&& other); // 方式6
具体方法如下:
方法1
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {
if (other)
other->incStrong(this);
}
方法2
template<typename T>
sp<T>::sp(const sp<T>& other)
: m_ptr(other.m_ptr) {
if (m_ptr)
m_ptr->incStrong(this);
}
方法3
template<typename T>
sp<T>::sp(sp<T>&& other)
: m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
方法4
template<typename T>
sp<T>& sp<T>::operator =(T* other) {
T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
if (other) other->incStrong(this);
if (oldPtr) oldPtr->decStrong(this);
if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
m_ptr = other;
return *this;
}
方法5