zoukankan      html  css  js  c++  java
  • Android framework回想(2) 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对象的强弱引用都加一.例如以下图:


  • 相关阅读:
    js内置date类
    获取下拉列表的value
    表单的隐藏与显示
    JavaScript
    CSS的相关属性
    CSS
    基于akka-http搭建restfull框架
    Netsharp配置文件
    nginx配置备忘
    docker安装radis
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5403221.html
Copyright © 2011-2022 走看看