android智能指针android::sp使用介绍

android::sp 是 Android 中的智能指针(Smart Pointer)的实现,用于管理对象的生命周期,避免手动管理内存泄漏等问题。它是 Android libutils 库中重要的一部分,常用于管理继承自 android::RefBase 的对象。

与标准库中的 std::shared_ptr 类似,android::sp 是引用计数智能指针。它会在对象的引用计数变为零时自动释放对象。此外,Android 还提供了 wp(弱指针),用于解决循环引用的问题。


sp 的特性

  1. 引用计数管理 :基于 android::RefBase 的引用计数,确保对象安全销毁。
  2. 自动释放资源 :当没有任何 sp 指针指向一个对象时,自动销毁该对象。
  3. 线程安全 :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。

cpp 复制代码
#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

代码详解

  1. sp<MyClass> sp1 = new MyClass();

    • sp 是一个模板类,sp<MyClass> 表示一个指向 MyClass 的智能指针。
    • 使用 new 创建一个 MyClass 对象,sp1 的构造函数会自动增加引用计数。
  2. sp<MyClass> sp2 = sp1;

    • 将 sp1 赋值给 sp2,它们会共享同一个 MyClass 对象,引用计数增加到 2。
  3. sp2 离开作用域

    • 当 sp2 离开作用域时,析构函数会减少引用计数(调用 decStrong),此时引用计数变为 1。
  4. sp1 离开作用域

    • 当 sp1 离开作用域时,引用计数变为 0,MyClass 对象被销毁(调用析构函数)。

注意事项

  1. 对象必须继承 RefBase:

    • sp 的引用计数功能依赖于 RefBase,如果对象没有继承 RefBase,则不能使用 sp。
  2. 避免循环引用:

    • 如果两个对象互相持有 sp 指针,会导致引用计数永远无法归零,产生内存泄漏。可以使用 wp(弱指针)解决这个问题。

扩展:使用弱指针

如果你需要避免循环引用,可以使用 android::wp(弱指针)。以下是一个简单示例:

cpp 复制代码
#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 使用。
相关推荐
拥小抱7 小时前
Compose 知识点
android
文章永久免费只为良心7 小时前
Web应用安全与防护_第三章_日志文件包含_从一道 CTFshow 题目讲透「日志投毒型 LFI → RCE」:原理、时序陷阱与全变种攻防手册
android·网络安全·渗透测试·漏洞危害·漏洞描述·日志投毒·红队指南
AIsoft_86897 小时前
学术讲座录音如何整理?录音APP可行吗
android·iphone
Patrick在香港10 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
海雅达手持终端PDA11 小时前
工业手持终端的“去手机化”演进:看海雅达如何以“同轴扫摄”终结工程妥协,重塑工业PDA新范式
android·物联网·智能手机·硬件工程·能源·制造·iot
booboosui12 小时前
删掉一个住在本机的 agent:8 处要清,顺序不能反
android
hcgeng12 小时前
Android获取崩溃日志
android
aqi0012 小时前
AI编程让鸿蒙开发电子书APP更加快捷
android·华为·harmonyos·鸿蒙·harmony
GY-9313 小时前
【Android】Android Studio 中的协程
android