用MediaPlayer说明sp的实现。sp是一个模板类,T是RefBase的子类。仅仅要继承于RefBase的类都能够使用sp。

binder类也继承RefBase类,binder的实现离不开RefBase。

用例如以下代码说说我遇到的疑惑。

201 static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)

 202 {                                                                                                                                  

 203     Mutex::Autolock l(sLock);

 204     MediaPlayer* const p = (MediaPlayer*)env->GetIntField(thiz, fields.context);

 205     return sp<MediaPlayer>(p);  //(1)c++两种初始化对象方法。

 206 } 



 413 static void

 414 android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)

 415 {

 416     ALOGV("start");

 417     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);  //(2)重载的操作符 = 

 418     if (mp == NULL ) {

 419         jniThrowException(env, "java/lang/IllegalStateException", NULL);

 420         return;

 421     }

 422     process_media_player_call( env, thiz, mp->start(), NULL, NULL ); //(3)

 423 }



sp是什么?

mp是sp<MediaPlayer>的对象,怎么的能调用到MediaPlayer的start函数呢?

sp就是个模板类。:



那mp怎么调用start()的呢?

查看sp源代码类。就会发现sp类中重写了->, 使->指向成员变量m_ptr(T* 模板參数的对象。如MediaPlayer),

mp->的返回值是m_ptr,即返回的是MediaPlayer的对象,当然能调用start方法了。



事实上sp中还重写了 & 和 = 操作符 。

mp的生命周期仅仅在android_media_MediaPlayer_start方法里面有效。方法运行完后就该释放。

这就有问题了,假设mp里面全部内存都释放了,别的地方还有引用。就会出现空指针。假设不释放,别的地方又不引用了,就内存泄露了。



怎么解决问题呢?

Android 引入了引用计数。weakref_impl类里面保存引用数目。记录了T被引用的次数。

引用次数为0时就释放。可是如过。sp<T1> 和sp<T2>之间相互引用,就相互依赖。没法释放了。这时又引入了强引用和弱引用。

sp wp RefBase T 类之间的关系例如以下图

用sp<MediaPlayer>分析,计数过程,

return sp<MediaPlayer>(p); 构造时。运行m_ptr->incStrong(this)方法,使MediaPlayer对象的强弱引用都加一。

getMediaPlayer运行完后。会调用匿名对象的析构函数~sp,运行m_ptr->decStrong(this),使MediaPlayer对象的强弱应用都减一。

在android_media_MediaPlayer_start函数里面,对mp进行赋值,使用的是重载的operator=,重载的过程也运行m_ptr->incStrong(this),也使MediaPlayer对象的强弱引用添加1。android_media_MediaPlayer_start函数运行完后,释放mp。会调用mp的析构函数,运行m_ptr->decStrong(this),也使MediaPlayer对象的强弱引用都加一.例如以下图:

Android framework回想(2) sp 和 wp sp对象的更多相关文章

  1. Android中的sp和wp指针

    经常会在android的framework代码中发现sp<xxx>和wp<xxx>这样的指针,平时看的时候都把他当成一个普通的指针封装过掉了,这几天终于忍不住了,想深入了解一下 ...

  2. Android 内核初识(7)RefBase、LightRefBase、sp和wp

    简介 RefBase是Android中所有对象的始祖,类似MFC中的CObject及Java中的Object对象.在Android中,RefBase结合sp和wp,实现了一套通过引用计数的方法来控制对 ...

  3. android RefBase、sp、wp

    首先RefBase在android的c++部分是作为一个所有类的基类,其作用跟Java中的Object类似 这个类中存在一个私有成员: weakref_impl* const mRefs;(weakr ...

  4. Android中px, ppi, dpi, dp, dip, sp概念解析

    Android中px, ppi, dpi, dp, dip, sp概念解析

  5. Android Framework中的线程Thread及它的threadLoop方法

    当初跟踪Camera的代码中的时候一直追到了HAL层,而在Framework中的代码看见了许很多多的Thread.它们普遍的特点就是有一个threadLoop方法.依照字面的意思应该是这个线程能够循环 ...

  6. 解析android framework下利用app_process来调用java写的命令及示例

    解析android framework下利用app_process来调用java写的命令及示例 在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是b ...

  7. <Android Framework 之路>BootAnimation(2)

    前言 上一篇主要讲解了BootAnimation是从何而来,如何启动,从开机,到SurfaceFlinger服务起来,然后到执行开机动画,如果要深入的看里面的代码,是需要花一定的时间的,我们旨在了解大 ...

  8. 怎样从C++代码直接訪问android framework层的WifiService

    说究竟,Java层的service就是就C++层的binder的封装.所以从原理上来讲通过C++代码直接訪问android framework层的service是全然可能的,这篇文章以訪问WifiSe ...

  9. <Android Framework 之路>Android5.1 Camera Framework(一)

    Android5.0 Camera Framework 简介 CameraService启动 CameraService是在MediaServer启动过程中进行的 main_mediaserver.c ...

随机推荐

  1. 【Hadoop】搭建完全分布式的hadoop【转】

    转自:http://www.cnblogs.com/laov/p/3421479.html 下面博文已更新,请移步 ↑ 用于测试,我用4台虚拟机搭建成了hadoop结构 我用了两个台式机.一个xp系统 ...

  2. python报错IndexError: list index out of range

    今天写个ping vpn的python脚本,报错IndexError: list index out of range 最后查看是python读取文件中出现空格 去掉空格即可

  3. (转载)ibatis:解决sql注入问题

    原文地址:http://blog.csdn.net/scorpio3k/article/details/7610973 对于ibaits参数引用可以使用#和$两种写法,其中#写法会采用预编译方式,将转 ...

  4. 小白学习安全测试(三)——扫描工具-Nikto使用

    扫描工具-Nikto #基于WEB的扫描工具,基本都支持两种扫描模式.代理截断模式,主动扫描模式 手动扫描:作为用户操作发现页面存在的问题,但可能会存在遗漏 自动扫描:基于字典,提高速度,但存在误报和 ...

  5. K8S Dashborad登陆认证文档

    K8S Dashboard是官方的一个基于WEB的用户界面,专门用来管理K8S集群,并可展示集群的状态.因为我们使用kubeadm搭建的集群会默认开启RABC(角色访问控制机制),所以我们必须要进行额 ...

  6. 如何用prometheus监控k8s集群中业务pod的metrics

    一般,我们从网上看到的帖子和资料, 都是用prometheus监控k8s的各项资源, 如api server, namespace, pod, node等. 那如果是自己的业务pod上的自定义metr ...

  7. kafka 查看队列信息

    https://blog.csdn.net/getyouwant/article/details/81209286?utm_source=blogxgwz8

  8. chunk writer 中需要对抛错的交易进行回滚,同时又要在其他表中记录是哪一笔交易记录失败

    首先根据我有限的知识判断,回滚之后进行写表,该写表动作只能使用listener来进行. 考虑使用的listener有:ItemWriteListener     StepExecutionListen ...

  9. 打FFT时中发现的卡常技巧

    题目:洛谷P1919 A*B Problem 加强版 我的代码完全借鉴boshi,然而他380ms我880ms...于是我通过彻底的卡(chao)常(dai)数(ma)成功优化到了380ms,都是改了 ...

  10. Linux详细安装步骤

    Linux详细安装步骤(CentOS_6.7_64位) 1.先安装好VMware10软件 2.验证VM是否安装成功: (有些机器在安装vmware的时候会出现一个错误:virtual XT,这需要重启 ...