Android系统之onFirstRef自动调用原理
前言:抽丝剥茧探究onFirstRef究竟为何在初始化sp<xxx>第一个调用?
1.onFirstRef调用位置
<1>.system/core/libutils/RefBase.cpp
#include <utils/RefBase.h>//1.初始化强指针
void RefBase::incStrong(const void* id) const
{weakref_impl* const refs = mRefs;refs->incWeak(id);refs->addStrongRef(id);const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);refs->mBase->onFirstRef();//调用onFirstRef
}//2.weakref_impl类
class RefBase::weakref_impl : public RefBase::weakref_type
{public:RefBase* const mBase; //RefBase定义全局变量mBase.
};
RefBase基类中定义调用onFirstRef(),如果有实例化sp<T> ttt = new Test()后,将会自动调用onFirstRef()函数。
<2>.system/core/libutils/RefBase.cpp
void RefBase::decStrong(const void* id) const
{weakref_impl* const refs = mRefs;refs->removeStrongRef(id);const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);//在调用析构函数时,自动调用onLastStrongRef()函数。refs->mBase->onLastStrongRef(id);}refs->decWeak(id);
}
在sp<T>的析构函数时,会自动调用onLastStrongRef();
2.onFirstRef定义位置
<1>.system/core/libutils/include/utils/RefBase.h
#include <utils/LightRefBase.h>
#include <utils/StrongPointer.h>class RefBase{protected:// Invoked after creation of initial strong pointer/reference.virtual void onFirstRef();//定义虚函数onFirstRef// Invoked when either the last strong reference goes away, or we need to undo// the effect of an unnecessary onIncStrongAttempted.virtual void onLastStrongRef(const void* id);//定义onLastStrongRefprivate:weakref_impl* const mRefs;};
在RefBase中定义虚函数onFirstRef()、onLastStrongRef()、以及weakref_impl类。
3.sp<T>实现位置
<1>.system/core/libutils/include/utils/StrongPointer.h
sp<T>构造函数
template<typename T>
sp<T>::sp(const sp<T>& other): m_ptr(other.m_ptr) {if (m_ptr)m_ptr->incStrong(this);
}
StrongPointer.h头文件中才是真正定义sp<T>智能指针的强指针的出处。
~sp<T>析构函数
template<typename T>
sp<T>::~sp() {if (m_ptr)m_ptr->decStrong(this);
}
4.Test onFirstRef Sample
写了一个sample帮助理解RefBase结构的onFirstRef原理。
<1>.Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := libcutils libutils liblog libbaseLOCAL_MODULE := test_onfirstRef
include $(BUILD_EXECUTABLE)
<2>.main.cpp
#define LOG_TAG "Main"#include <utils/Log.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>//using namespace android;/*
1.system/core/libutils/include/utils/RefBase.hclass RefBase{protected:// Invoked after creation of initial strong pointer/reference.virtual void onFirstRef();};2.system/core/libutils/include/utils/Threads.hclass Thread : virtual public RefBase{public:virtual status_t run(const char* name,int32_t priority = PRIORITY_DEFAULT, size_t stack = 0);private:virtual bool threadLoop() = 0;};3.system/core/libutils/Threads.cppstatus_t Thread::run(const char* name, int32_t priority, size_t stack){res = androidCreateRawThreadEtc(_threadLoop,this, name, priority, stack, &mThread);}
*/class Test: public android::RefBase {
public:// Test(int id, char *name){// printf("xxx------->%s(), line = %d, id = %d, name = %s\n",__FUNCTION__,__LINE__,id,name);// }void onFirstRef(){printf("xxx------->%s(), line = %d\n",__FUNCTION__,__LINE__);}void onLastStrongRef(__unused const void* id){printf("xxx------->%s(), line = %d\n",__FUNCTION__,__LINE__);}bool onIncStrongAttempted(__unused uint32_t flags, __unused const void* id){printf("xxx------->%s(), line = %d\n",__FUNCTION__,__LINE__);return true;}void onLastWeakRef(__unused const void* id){printf("xxx------->%s(), line = %d\n",__FUNCTION__,__LINE__);}
};void print(android::sp<Test> tt){printf("xxx------------->%s(), line = %d, strong_count = %d\n",__FUNCTION__,__LINE__,tt->getStrongCount());
}int main(){//char name[] = "onFirstRef";//1.没有调用onFirstRef//new Test(1234, name);//2.sp强智能指针自动调用onFirstRefandroid::sp<Test> test = new Test(); //invoke onFirstRef() and onLastStrongRef().printf("xxx------------->%s(), line = %d, strong_count = %d\n",__FUNCTION__,__LINE__,test->getStrongCount());//3.wp弱智能指针// android::wp<Test> wp_test = new Test();// android::sp<Test> sp_test = wp_test.promote(); // invoke onLastStrongRef()// printf("xxx------------->%s(), line = %d, strong_count = %d\n",__FUNCTION__,__LINE__,sp_test->getStrongCount());//4.将普通引用修改为常引用,为了避免函数使用时,防止test对象被修改.const android::sp<Test> &test = new Test(); //invoke onFirstRef() and onLastStrongRef().//android::sp<Test> &test = new Test(); //编译报错printf("xxx------------->%s(), line = %d, strong_count = %d\n",__FUNCTION__,__LINE__,test->getStrongCount());print(new Test());return 0;
}
相关文章:
Android系统之onFirstRef自动调用原理
前言:抽丝剥茧探究onFirstRef究竟为何在初始化sp<xxx>第一个调用?1.onFirstRef调用位置<1>.system/core/libutils/RefBase.cpp#include <utils/RefBase.h>//1.初始化强指针 void RefBase::incStrong(const void* id) const {weakref_i…...
ipv6上网配置
一般现在的宽带都已经支持ipv6了,但是需要一些配置才能真正用上ipv6。记录一下配置过程。 当前测试环境为移动宽带,光猫下面接了一个路由器,家里所有的设备都挂到这个路由器下面的。 1. 光猫改桥接 光猫在使用路由模式下,ipv6无…...
python实现聚类技术—复杂网络社团检测 附完整代码
实验内容 某跆拳道俱乐部数据由 34 个节点组成,由于管理上的分歧,俱乐部要分解成两个社团。 该实验的任务即:要求我们在给定的复杂网络上检测出两个社团。 分析与设计 实验思路分析如下: 聚类算法通常可以描述为用相似度来衡量两个数据的远近,搜索可能的划分方案,使得目标…...
如何判断两架飞机在汇聚飞行?(如何计算两架飞机的航向夹角?)内含程序源码
ok,在开始一切之前,让我先猜一猜,你是不是想百度“二维平面下如何计算两个移动物体的航向夹角?”如果是,那就请继续往下看。 首先,我们要明确一个概念:航向角≠航向夹角!࿰…...
Scipy稀疏矩阵bsr_array
文章目录基本原理初始化内置方法基本原理 bsr,即Block Sparse Row,bsr_array即块稀疏行矩阵,顾名思义就是将稀疏矩阵分割成一个个非0的子块,然后对这些子块进行存储。通过输入维度,可以创建一个空的bsr数组࿰…...
LeetCode笔记:Weekly Contest 332
LeetCode笔记:Weekly Contest 332 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 1. 解题思路2. 代码实现 比赛链接:https://leetcode.com/contest/weekly-contest-332/ 1. 题目一…...
autox.js在vscode(win7)与雷神模拟器上的开发环境配置
目录 下载autox.js 安装autox.js? 在电脑上搭建autox.js开发环境 安装vscode 安装autox.js插件 雷神模拟器连接vscode 设置雷神模拟器IP 设置autox.js应用IP地址等 下载autox.js 大体来说,就是一个运行在Android平台上的JavaScript 运行环境 和…...
创建阿里云物联网平台
创建阿里云物联网平台 对云平台设备创建过程做记录,懒得再看视频 文章参考视频:https://www.bilibili.com/video/BV1jP4y1E7TJ?p26&vd_source50694678ae937a743c59db6b5ff46c31 阿里云:https://www.aliyun.com 1.物联网平…...
【链式二叉树】数据结构链式二叉树的(万字详解)
前言: 在上一篇博客中,我们已经详解学习了堆的基本知识,今天带大家进入的是二叉树的另外一种存储方式----“链式二叉树”的学习,主要用到的就是“递归思想”!! 本文目录1.链式二叉树的实现1.1前置说明1.2结…...
Koa2篇-简单介绍及使用
一.简介koa2是基于 Node.js 平台的下一代 web 开发框架, 致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 可以避免异步嵌套. express中间件是异步回调,Koa2原生支持async/await二.async/awaitconst { rejects } require("assert"); const { resolve } req…...
Linux ALSA 之十一:ALSA ASOC Path 完整路径追踪
ALSA ASOC Path 完整路径追踪一、ASoc Path 简介二、ASoc Path 完整路径2.1 tinymix 设置2.2 完整路径 route一、ASoc Path 简介 如前面小节所描述,ASoc 中 Machine Driver 是 platform driver 和 codec driver 的粘合剂,audio path 离不开 FE/BE/DAI l…...
【Spring Cloud总结】1、服务提供者与服务消费者快速上手
目录 文件结构 代码 1、api 1.1实体类(Dept ) 1.2数据库 2、provider 2.1 DeptController 2.2 DeptDao 2.3 DeptService 2.4 DeptServiceImpl 2.5 application.yml 3、consumer 3.1 ConfigBean 3.2 DeptConsumerController 测试 1.启动…...
若依项目学习之登录生成验证码
若依项目学习之登录生成验证码 使用DefaultKaptcha生成验证码 /*** 验证码配置* * author ruoyi*/ Configuration public class CaptchaConfig {/*** 生成字符类型的验证码**/Bean(name "captchaProducer")public DefaultKaptcha getKaptchaBean(){DefaultKaptcha…...
计算机网络5:数据在两台计算机之间是怎样传输的?
数据在两台计算机之间的传输总的来说包括了封装和解封两个过程 封装(5层协议) 以传送一张图片为例 **应用层:**将jpg格式的图片数据转化成计算机可以识别的0101的二进制的比特流 **传输层:**将应用层传输下来的数据进行分段&…...
就现在!为元宇宙和Web3对互联网的改造做准备!
欢迎来到Hubbleverse 🌍 关注我们 关注宇宙新鲜事 📌 预计阅读时长:8分钟 本文仅代表作者个人观点,不代表平台意见,不构成投资建议。 如今,互联网是各种不同的网站、应用程序和平台的集合。由于彼此分离…...
【mysql数据库】
目录SQL数据库分页聚合函数表跟表之间的关联关系SQL中怎么将行转成列SQL注入将一张表的部分数据更新到另一张表WHERE和HAVING的区别索引索引分类如何创建及保存MySQL的索引?怎么判断要不要加索引?索引设计原理只要创建了索引,就一定会走索引吗…...
【测试开发】web 自动化测试 --- selenium4
目录1. 什么是自动化为什么要做自动化2. 为什么选择selenium作为我使用的web自动化工具3. 什么是驱动?驱动的工作原理是什么5. 第一个自动化程序演示6. selenium基本语法6.1 定位元素的方法6.2 操作页面元素6.3 等待6.4 信息打印获取当前页面句柄,窗口切…...
Elasticsearch7.8.0版本进阶——路由计算
目录一、路由计算1.1、路由计算的前提理解1.2、路由计算的概述1.3、路由计算的概述一、路由计算 1.1、路由计算的前提理解 当索引一个文档的时候,文档会被存储到一个主分片中。Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时…...
c#反射-获取属性和字段的值
演示类 示例类具有一个私有实例字段,一个实例属性,一个实例字段,一个静态私有属性。 class Fight {private int hp;public int Hp{get > hp; set{if (value > 0){ hp value; }else if (-value > Def){ hp value - Def; }}}publi…...
前后端分离-小项目-1前端布局
技术栈前后端分离开发,前端主体框架Vue3后端基础框架Spring-Boot1.前端技术栈:Vue3AxiosElementPlus2.后端技术栈:Spring BootMyBatis Plus3.数据库-MySQL4.项目的依赖管理-Maven5.分页-MyBatis Plus的分页插件环境搭建安装Node.js LTSnode.j…...
基于jsp的网络电子相册的设计与实现
技术:Java、JSP等摘要:随着科学技术的不断进步,云技术以及大数据的不断完善,越来越多的网络忠实用户告别了冲洗相片的时代,他们更喜欢将相片上传至网络,这样就省去了携带和查找的麻烦,随时随地只…...
Python快速上手系列--类--详解篇
本章是自动化测试的真正开始,因为在后续的过程中,你会接触到unittest框架,pytest框架,而不仅仅只是写一个函数selenium脚本这么简单了。1、创建类1.1、了解类我们首先了解一下,为什么要使用类,类可以拿来干…...
Dubbo基本原理和用法讲解
Dubbo基本原理和用法讲解 序言:学习一项新技术,一般从是什么、为什么、怎么用三个方面进行学习。本篇文章也不例外,笔者将从Dubbo是什么?、为什么会产生Dubbo技术?、如何在项目中使用Dubbo技术。最后,笔者…...
TCP详解及面试相关问题
文章目录1、计算机模型2、客户端和服务端通信——TCP协议(1)socket套接字(2)TCP三次握手——创建socket(3)连接的本质(4)TCP四次挥手——释放socket资源(5)TC…...
LVGL V9.0基于VS2022仿真搭建
完整Demo,lvgl,lvgl_drivers相关资料下载 链接:https://pan.baidu.com/s/1DNJeHdoaPyfe1BsLb9wjRg 提取码:wov7 其它资料下载 链接:https://pan.baidu.com/s/1nV9jojPEPWSWZdYhaCZWTA 提取码:91j8 下载资料后解压文…...
多线程面试题开胃菜2(5道)
一.一个线程的生命周期有哪几种状态?它们之间如何流转的?NEW:毫无疑问表示的是刚创建的线程,还没有开始启动。RUNNABLE: 表示线程已经触发 start()方式调用,线程正式启动,线程处于运行中状态。BLOCKED&…...
第三次作业
一、单表查询素材: 表名:worker-- 表中字段均为中文,比如 部门号 工资 职工号 参加工作 等CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10) N…...
基础算法(直接插入,希尔排序,快排,归并,折半查找)
/*直接插入:把待排序序列分为有无序区和和无序区,使用无序区的数据一次插入倒有序区中,最终结果尾有序序列 1> 把数据分为有序区和无序区,默认第一个元素在有序区,剩下在无序区 2> 外层循环,循环无…...
电子学会2022年12月青少年软件编程(图形化)等级考试试卷(一级)答案解析
目录 一、单选题(共25题,共50分) 二、判断题(共10题,共20分) 三、编程题(共2题,共30分) 青少年软件编程(图形化)等级考试试卷(一级) 一、单选题(共25题,共50分) 1. 小明想在开始…...
基于JAVA的超级玛丽设计与实现
技术:Java等摘要:随着计算机技术及网络技术的不断发展,电子游戏越来越普及。经典游戏“超级玛丽”因其本身所具有的娱乐性与教育意义而被人们广泛接受,在广大的青少年玩家中享有极高的知名度。Java语言作为一种完全面向对象的程序…...
wordpress 防火墙/百度百科词条
a转载于:https://www.cnblogs.com/menggucaoyuan/archive/2013/04/23/3036903.html...
大连网站建设培训班/新手如何找cps推广渠道
基本了解:mysql数据库为关系型数据库,个关系型数据库由一个或数个表格组成,表格中肯定有键(键(key): 表中用来识别某个特定的人物的方法, 键的值在当前列中具有唯一性。)登录mysql(记得配置环境变量)管理员模式打开cmd启动服务net start mysq…...
无锡网站关键词推广/seo这个行业怎么样
RSPdx多天线端口14位SDR接收器性能一览SDRplay RSPdx是对流行的RSP 2和RSP 2 pro多天线接收器的完全重新设计。它是宽带全功能14位SDR,涵盖从1 kHz到2 GHz的整个RF频谱。结合现成的SDR接收器软件(包括SDRplay提供的SDRuno)的功能,您可以一次监视高达10 M…...
做快三网站/竞价推广是做什么的
第 2 部分 - 对 Android 应用程序包进行签名 ✏️ 在 GitHub 上编辑 可离线查看的 PDF下载 PDF 本指南介绍如何对 Android 应用程序包进行签名。 如果使用较旧版本的 Xamarin Studio(版本 5.9 之前),请参阅 Xamarin Studio 5.8 及更低版…...
网站第三方评价如何做/想卖产品怎么推广宣传
最近在为公司实施做了一个工具,Silverlight部署早已是轻车熟路, 但对于非技术人员来说却很是头疼的一件事,当到现场实施碰到客户情况也各不相同, 急需一个类似系统备份的"一键工具"快速实现应用程序部署和数据库进行关联. 网上关于这方面资源也比较混乱,其中对于IIS的…...
wordpress安全漏洞/什么是seo推广
“应用软件创造客户价值”是我们的经营理念。我们强调客户的价值,因为软件企业生存的基础是客户的价值,如果不能为客户带来价值的软件,软件也就没有价值。所以我们把这样的理念作为公司经营的发展方向,我们始终把公司的价值体系建…...