android::sp
是 Android 中的智能指针(Smart Pointer)的实现,用于管理对象的生命周期,避免手动管理内存泄漏等问题。它是 Android libutils
库中重要的一部分,常用于管理继承自 android::RefBase
的对象。
与标准库中的 std::shared_ptr
类似,android::sp
是引用计数智能指针。它会在对象的引用计数变为零时自动释放对象。此外,Android 还提供了 wp
(弱指针),用于解决循环引用的问题。
sp
的特性
- 引用计数管理:基于
android::RefBase
的引用计数,确保对象安全销毁。 - 自动释放资源:当没有任何
sp
指针指向一个对象时,自动销毁该对象。 - 线程安全:
sp
和wp
提供线程安全的引用计数操作。
使用场景
sp
通常用于管理继承自 android::RefBase
的对象。在 Android 的 HAL(硬件抽象层)和 Binder 通信中非常广泛。
实现原理
sp
的核心是对目标对象的引用计数进行管理。目标对象必须继承 android::RefBase
,因为 RefBase
提供了引用计数的功能。
RefBase
提供了以下方法:
incStrong(const void* id)
:增加强引用计数。decStrong(const void* id)
:减少强引用计数。getStrongCount()
:获取当前的强引用计数。
简单示例代码
以下是一个完整的例子,演示如何使用 android::sp
和 RefBase
。
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <iostream>
using namespace android;
// 一个继承自 RefBase 的类
class MyClass : public RefBase {
public:
MyClass() {
std::cout << "MyClass Constructor" << std::endl;
}
~MyClass() {
std::cout << "MyClass Destructor" << std::endl;
}
void display() {
std::cout << "Hello from MyClass!" << std::endl;
}
};
int main() {
// 创建智能指针
sp<MyClass> sp1 = new MyClass();
sp1->display();
{
// 创建另一个智能指针,引用同一个对象
sp<MyClass> sp2 = sp1;
std::cout << "sp2 created, reference count: " << sp2->getStrongCount() << std::endl;
} // sp2 离开作用域,引用计数减少
std::cout << "sp2 out of scope, reference count: " << sp1->getStrongCount() << std::endl;
// 离开主作用域,sp1 被销毁,引用计数为 0,对象销毁
return 0;
}
输出结果
运行上面的代码,输出类似以下内容:
MyClass Constructor
Hello from MyClass!
sp2 created, reference count: 2
sp2 out of scope, reference count: 1
MyClass Destructor
代码详解
-
sp<MyClass> sp1 = new MyClass();
sp
是一个模板类,sp<MyClass>
表示一个指向MyClass
的智能指针。- 使用
new
创建一个MyClass
对象,sp1
的构造函数会自动增加引用计数。
-
sp<MyClass> sp2 = sp1;
- 将
sp1
赋值给sp2
,它们会共享同一个MyClass
对象,引用计数增加到 2。
- 将
-
sp2
离开作用域- 当
sp2
离开作用域时,析构函数会减少引用计数(调用decStrong
),此时引用计数变为 1。
- 当
-
sp1
离开作用域- 当
sp1
离开作用域时,引用计数变为 0,MyClass
对象被销毁(调用析构函数)。
- 当
注意事项
-
对象必须继承
RefBase
:sp
的引用计数功能依赖于RefBase
,如果对象没有继承RefBase
,则不能使用sp
。
-
避免循环引用:
- 如果两个对象互相持有
sp
指针,会导致引用计数永远无法归零,产生内存泄漏。可以使用wp
(弱指针)解决这个问题。
- 如果两个对象互相持有
扩展:使用弱指针
如果你需要避免循环引用,可以使用 android::wp
(弱指针)。以下是一个简单示例:
#include <utils/RefBase.h>
#include <iostream>
using namespace android;
class MyClass : public RefBase {
public:
MyClass() {
std::cout << "MyClass Constructor" << std::endl;
}
~MyClass() {
std::cout << "MyClass Destructor" << std::endl;
}
void display() {
std::cout << "Hello from MyClass!" << std::endl;
}
};
int main() {
sp<MyClass> sp1 = new MyClass();
wp<MyClass> wp1 = sp1; // 创建一个弱指针
{
sp<MyClass> sp2 = wp1.promote(); // 从弱指针提升为强指针
if (sp2 != nullptr) {
sp2->display();
}
} // sp2 离开作用域
sp1 = nullptr; // 强引用计数归零,对象销毁
if (wp1.promote() == nullptr) {
std::cout << "Object already destroyed!" << std::endl;
}
return 0;
}
总结
android::sp
是 Android 中的智能指针,用于管理派生自RefBase
的对象。- 它通过引用计数实现内存管理,避免手动
new
和delete
。 - 使用
sp
时要注意避免循环引用,可以结合wp
使用。