当前位置: 首页 > news >正文

Android 自己的智能指针

在 Android 系统中,强指针模板类(sp<T> 是一种基于引用计数的智能指针实现,专门用于管理对象的生命周期。它被广泛用于 Android Framework 的底层(Native 层/C++ 代码),尤其是与 Binder 通信相关的模块。

1. sp<T> 的定义与作用

  • 模板类sp<T> 是一个模板类(定义在 <utils/StrongPointer.h> 中),通过泛型支持任意类型的对象。
  • 强引用语义:通过引用计数(Reference Counting)跟踪对象的使用情况,确保对象在不再被任何指针引用时自动释放内存。
  • 设计目标:解决 Android 系统中 Native 层对象生命周期管理的复杂性,避免内存泄漏和野指针问题。

2. 强指针服务对象

引用计数机制
  • 每个被 sp<T> 管理的对象必须继承自 RefBase(定义在 <utils/RefBase.h>)。
  • RefBase 提供了两个引用计数器:
    • 强引用计数(Strong Count):由 sp<T> 管理,归零时对象被销毁。
    • 弱引用计数(Weak Count):由 wp<T>(弱指针)管理,归零时对象的控制块被释放(但对象内存可能已被强引用释放)。
sp<T> 的实现原理
  1. 构造 sp<T>
    sp<T> 指向一个对象时,会调用 RefBase::incStrong() 增加强引用计数。

    template<typename T>
    sp<T>::sp(T* other) : m_ptr(other) {if (other) other->incStrong(this);
    }
    
  2. 析构 sp<T>
    sp<T> 超出作用域或被重置时,调用 RefBase::decStrong() 减少强引用计数。若计数归零,销毁对象。

    template<typename T>
    sp<T>::~sp() {if (m_ptr) m_ptr->decStrong(this);
    }
    
  3. 赋值与拷贝
    拷贝或赋值操作会调整引用计数,确保新旧指针的正确管理:

    sp<ProcessState> p1 = new ProcessState();
    或者  sp<ProcessState> p1(new ProcessState());
    // 强引用计数=1
    sp<ProcessState> p2 = p1;                 // 强引用计数=2
    

3. sp<T>RefBase 的关系

  • 对象必须继承 RefBase
    只有继承自 RefBase 的类才能被 sp<T> 管理。例如:

    class ProcessState : public virtual RefBase {// ...
    };
    
  • RefBase 的关键方法

    • incStrong():增加强引用计数。
    • decStrong():减少强引用计数,可能触发对象销毁。
    • onFirstRef():当强引用计数从 0 变为 1 时调用(首次被引用)。
    • onLastStrongRef():当强引用计数归零时调用(即将销毁)。

4. 使用场景示例

示例 1:Binder 代理对象的生命周期管理

在 Binder 通信中,客户端通过 sp<IBinder> 持有服务端的代理对象:

// 获取 ServiceManager 的代理
sp<IServiceManager> sm = defaultServiceManager();// 获取 BatteryService 的 Binder 代理对象
sp<IBinder> binder = sm->getService(String16("battery"));// 将 IBinder 转换为具体的服务接口
sp<IBatteryService> batteryService = interface_cast<IBatteryService>(binder);
  • sp<T> 确保代理对象在不再被使用时自动释放。
示例 2:单例模式的资源管理

ProcessState 单例中,使用 sp<T> 确保全局唯一实例的正确释放:

sp<ProcessState> ProcessState::self() {static sp<ProcessState> gProcess(new ProcessState);return gProcess;
}

5. sp<T> vs C++ 标准智能指针

特性sp<T> (Android)std::shared_ptr<T> (C++11)
依赖对象基类必须继承 RefBase无要求(通过 std::enable_shared_from_this 可选)
性能优化为嵌入式系统优化,轻量级通用实现,可能略重
线程安全引用计数操作是原子的(线程安全)默认线程安全(依赖实现)
弱指针支持通过 wp<T> 实现通过 std::weak_ptr<T> 实现
内存开销每个对象附带 RefBase 的控制块每个 shared_ptr 有单独的控制块

6. 注意事项

  1. 循环引用
    sp<T> 无法自动处理循环引用(如对象 A 持有 sp<B>,对象 B 持有 sp<A>),需结合 wp<T>(弱指针)打破循环。

  2. 继承 RefBase
    若类未继承 RefBase,使用 sp<T> 会导致编译错误。

  3. 跨模块传递
    确保对象的所有权通过 sp<T> 明确传递,避免裸指针(T*)脱离智能指针管理。

  4. 线程安全
    虽然 sp<T> 的引用计数操作是原子的,但对象本身的线程安全性需开发者自行保证。


http://www.mrgr.cn/news/98006.html

相关文章:

  • 数据仓库标准库模型架构相关概念浅讲
  • C语言--求n以内的素数(质数)
  • 5️⃣ Coze+AI应用基础教学(2025年全新版本)
  • 自动化测试常用函数
  • Java习题:合并两个有序数组
  • MySQL 进阶 - 2 ( 12000 字详解)
  • C语言超详细指针知识(一)
  • 【学习笔记】头文件中定义函数出现重复定义报错
  • MySQL学习笔记7【InnoDB】
  • 【数据结构】排序
  • <C#> 详细介绍.NET 依赖注入
  • AD9253 LVDS 高速ADC驱动开发
  • ViewModel vs AndroidViewModel:核心区别与使用场景详解
  • TaskFlow开发日记 #1 - 原生JS实现智能Todo组件
  • Shell 编程之条件语句
  • Windows下编译SALOME
  • AI大模型学习六:‌小米8闲置,通过Termux安装ubuntu做个随身服务器
  • UE的AI判断队伍归属的机制:IGenericTeamAgentInterface接口
  • 代码随想录第15天:(二叉树)
  • 图书管理系统(Python)