Android framework回顾 sp 和 wp sp对象

用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对象的强弱引用都加一.

时间: 2024-08-08 13:47:47

Android framework回顾 sp 和 wp sp对象的相关文章

Android framework回顾(3)binder利用及IBinder BpRefbase IInterface INTERFACE 之间关系

status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, int index, audio_devices_t device){ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();// if (aps == 0) return PERMISSION_DENIED; return aps->set

android RefBase、sp、wp

首先RefBase在android的c++部分是作为一个所有类的基类,其作用跟Java中的Object类似 这个类中存在一个私有成员: weakref_impl* const mRefs;(weakref_impl是weakref_type的子类) 这个mRefs是“影子对象”,是管理一个对象的引用计数的关键 RefBase的构造中mRefs(new weakref_impl(this)),new一个weakref_impl对象,weakref_impl的构造形参是RefBase的指针 同时会初

在Android中,px,dp,dip,sp的不同之处

       最近在学习Android开发,一直没有弄清楚px,dp,dip,sp的区别.今天正好有时间,就花时间研究了一下.     众所周知,Android厂商非常多,各种尺寸的Android手机.平板层出不穷.导致了Android生态环境的碎片化现象越来越严重.Google公司为了解决分辨率过多的问题,在Android的开发文档中定义了px,dp,dip,sp,方便开发者适配不同分辨率的Android设备. 1.基础知识:     mm:millimeters 毫米,长度单位.     i

25 Android中dip、dp、sp、pt和px的区别

http://blog.sina.com.cn/s/blog_6499f8f101014ipq.html 25 Android中dip.dp.sp.pt和px的区别,布布扣,bubuko.com

RefBase, sp和wp (2)

1. 通过wp创建sp的例子, 如: int main() { A* pA = new A(); wp<A> wpA(pA);                             // 弱引用计数为1, 强引用计数为初始值0x1000000. sp<A> spA = wpA.promote();             // 通过promote()得到一个sp. } 2. promote函数的实现: template<typename T> sp<T>

Android的px、dip、sp的区别

Android的px.dip.sp的区别 我们在页面布局的时候,经常会设置容器的长度,但是到底该使用哪个作为长度的单位而懊恼. 在Android中支持的描述大小区域的类型有以下几种: px(pixels)——像素:不同的设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多. dip(device independent pixels)——设备独立像素:这个和设备硬件有关,一般哦我们为了支持WCGA.HVGA和QVGA推荐使用这个,不依赖于像素.等同于dp.是一种与密度无关的像

Android framework camera回顾-Camera CameraClient ICamera之间关系(1)-cl和c-&gt;mCamera去哪儿

status_t Camera::connectLegacy(int cameraId, int halVersion,  const String16& clientPackageName,    int clientUid,    sp<Camera>& camera)   {                                 sp<Camera> c = new Camera(cameraId);      sp<ICameraClient

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

当初跟踪Camera的代码中的时候一直追到了HAL层,而在Framework中的代码看见了若干个Thread.它们普遍的特点就是有一个threadLoop方法.按照字面的意思应该是这个线程能够循环处理数据.对应我想到到了java上层中的HandlerThread,这个估计也差不多,但当时心里总有一个疙瘩,想弄清楚它到底是怎么循环起来的. Android中java世界的Thread 先来看看java是怎么创建一个线程的.这个是最舒服的,也是我最熟悉的. new Thread(new Runnabl

如何从C++代码直接访问android framework层的WifiService

说到底,Java层的service就是就C++层的binder的封装,所以从原理上来讲通过C++代码直接访问android framework层的service是完全可能的,这篇文章以访问WifiService为例,讲解如何去实现这个功能. 费话少说,直接上代码: WifiTest.cpp #include <sys/types.h> #include <unistd.h> #include <grp.h> #include <binder/IPCThreadSt