用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. Linux信号(signal)机制【转】

    转自:http://gityuan.com/2015/12/20/signal/ 信号(signal)是一种软中断,信号机制是进程间通信的一种方式,采用异步通信方式 一.信号类型 Linux系统共定义 ...

  2. linux 串口驱动(三) 【转】

    转自:http://blog.chinaunix.net/uid-27717694-id-3495825.html 三.串口的打开在用户空间执行open操作的时候,就会执行uart_ops->o ...

  3. 微服务架构及Eureka简介

    一.微服务架构 服务提供者.服务消费者.服务发现组件这三者之间的关系: 各个微服务在启动时,将自己的网络地址等信息注册到服务发现组件中,服务发现组件会存储这些信息. 服务消费者可从服务发现组件查询服务 ...

  4. 07 Go 1.7 Release Notes

    Go 1.7 Release Notes Introduction to Go 1.7 Changes to the language Ports Known Issues Tools Assembl ...

  5. python爬虫-基础

    所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地. 类似于使用程序模拟IE浏览器的功能,把URL作为HTTP请求的内容发送到服务器端, 然后读取服务器端的响应资源. 1.浏 ...

  6. Windows xp下安装sql server2005所碰到的一些问题及解决方法

    之前提到的帮老板做的一个中船重工的项目,其中的一个子模块:windows下获取特定进程网络流量 一开始是用VS2010做的,后来老板把项目书拿给我看后,明确要求开发环境为VS2005和Sql serv ...

  7. 【AtCoder】AGC025题解

    A - Digits Sum 枚举即可 代码 #include <bits/stdc++.h> #define fi first #define se second #define pii ...

  8. spark streaming限制吞吐

    使用spark.streaming.receiver.maxRate这个属性限制每秒的最大吞吐.官方文档如下: Maximum rate (number of records per second) ...

  9. oj提交时常见错误归纳

    Presentation Error: 常见的PE错误应该有以下的几种情况: 每行输出之后有空行 每两行输出之间有空行 一行中,每个输出数字(或字符串,等)之间有空格 一行中,每个输出数字(或字符串, ...

  10. canvas-圆弧形可拖动进度条

    一.效果如下: See the Pen XRmNRK by pangyongsheng (@pangyongsheng) on CodePen. 链接dome 二. 本文是实现可拖动滑块实现的基本思路 ...