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. 线程安全spwp 提供线程安全的引用计数操作。

使用场景

sp 通常用于管理继承自 android::RefBase 的对象。在 Android 的 HAL(硬件抽象层)和 Binder 通信中非常广泛。


实现原理

sp 的核心是对目标对象的引用计数进行管理。目标对象必须继承 android::RefBase,因为 RefBase 提供了引用计数的功能。

RefBase 提供了以下方法:

  • incStrong(const void* id):增加强引用计数。
  • decStrong(const void* id):减少强引用计数。
  • getStrongCount():获取当前的强引用计数。

简单示例代码

以下是一个完整的例子,演示如何使用 android::spRefBase

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 的对象。
  • 它通过引用计数实现内存管理,避免手动 newdelete
  • 使用 sp 时要注意避免循环引用,可以结合 wp 使用。
相关推荐
LING32 分钟前
RN容器启动优化实践
android·react native
恋猫de小郭3 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker8 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴8 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭18 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab19 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin