深入浅出

第六章、Android的对象管理

在Java中,不再使用的对象会通过gc机制来自己主动回收。而Android系统执行时库层代码是由C++编写的,在C++中创建的对象通常使用指针来操作,一旦使用不当。轻则造成内存泄漏,重则造成系统崩溃。

只是在Android源代码实现中,它为我们提供了智能指针来对C++对象进行管理。这使得程序猿不再须要关注对象的生命周期、对象是否已经释放。

本章主要内容例如以下:

l 智能指针

l RefBase类

l 强指针

l 弱指针

5.1 智能指针

在C++代码中创建对象有两种方式:创建栈对象和创建堆对象。

创建栈对象:

class A{

public:

         A();

         ~A();

private:

         intmVar1;

         intmVar2;

};

int main(int argc, char** argv){

Aa();

return0;

}

上述代码前面定义了一个类A。然后使用A a()来创建类A的对象a。这时a对象是在栈空间上分配的。我们能够通过“对象名.成员名”来訪问对象的成员。当退出了main函数作用域。a对象自己主动释放。

栈对象的特点为:创建简单。使用后自己主动释放。

可是有的场合我们希望创建的对象是个“全局对象”,即:对象保存下来直到合适的时间再被释放。这时我们就要创建一个堆对象。堆对象的创建例如以下:

A *pa = new A();

上述代码首先在栈上创建了A类的对象指针pa,然后在堆中为A对象分配空间,将对象地址赋值给pa。

C++要求全部动态创建的堆对象都要手动通过delete来释放对象空间,如同C中的malloc和free一样。尽管这样的方式创建的对象能够一直保存到手动释放。可是假设定义了大量堆对象。而忘记了释放,easy造成“内存泄漏”。另外。假设堆对象已经释放了,其他代码再通过指针訪问这个对象时,就会造成系统崩溃。这时,我们希望有一个“智能管理者”,它能自己主动记录下一个对象被引用的次数,当一个对象的引用计数不为“0”。说明它还在被使用。假设引用计数为“0”,说明该对象没有人再去使用它,这时“自己主动”去释放掉该对象。这个“智能管理者”就是智能指针。

智能指针(smartpointer)一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类的 对象被引用次数。

每次创建类的新对象时。初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并添加与之相应的引用计数;对一个对象进行赋值时,赋值操作符“=”降低左操作数所指对象的引用计数(假设引用计数为减至0。则删除对象),并添加右操作数所指对象的引用计数。调用析构函数时,析构函数降低引用计数(假设引用计数减至0。则删除对象)。而且智能指针类中重载了operator->和operator*来返回原始对象指针,这样智能指针使用起来就像原始对象指针一起。

Android中实现了两种智能指针:轻量级指针和强弱指针。

5.2 轻量级指针

Android智能指针的设计者为了隐藏智能指针的实现细节,通常将要隐藏的代码放到基类中,然后让子类去继承该基类,通过复用代码,降低编程人员工作量和程序设计的复杂程序。在轻量级指针设计时,设计者将智能指针引用计数操作接口封装到了LightRefBase这个基类中。当我们使用智能指针时,仅仅要继承LightRefBase类,那么子类对象就具有智能管理功能了。LightRefBase类定义例如以下:

 @frameworks/base/include/utils/RefBase.h

template <class T>

class LightRefBase

{

public:

         inlineLightRefBase() : mCount(0) { }          //初始化引用计数值为0

         inlinevoid incStrong(const void* id) const {                   //添加引用计数

                   android_atomic_inc(&mCount);

         }

         inlinevoid decStrong(const void* id) const {                  //降低引用计数

                   if(android_atomic_dec(&mCount) == 1) {

                            deletestatic_cast<const T*>(this);

                   }

         }

         //!DEBUGGING ONLY: Get current strong ref count.

         inlineint32_t getStrongCount() const {                //返回当前引用计数值

                   returnmCount;

         }

protected:

         inline~LightRefBase() { }

private:

         mutablevolatile int32_t mCount;                         //定义引用计数变量mCount

};

轻量级指针类定义非常easy。类中定义一个mCount变量,它的初始化值为0,另外,这个类还提供两个成员函数incStrong和decStrong来维护引用计数器的值。这两个函数就是提供给智能指针来调用的。这里要注意的是,在decStrong函数中,假设当前引用计数值为1。那么当减1后就会变成0,于是就会delete这个对象。

 

         上述类仅仅是定义了引用计数变量和引用计数的两个操作函数,真正对引用计数进行管理的是智能指针类sp。

@frameworks/base/include/utils/RefBase.h

template <typename T>

class sp

{

public:

   typedef typename RefBase::weakref_typeweakref_type;

    inlinesp() : m_ptr(0) { }

    sp(T*other);

   sp(const sp<T>& other);

   template<typename U> sp(U* other);

   template<typename U> sp(const sp<U>& other);

    ~sp();

    //Assignment 

   sp& operator = (T* other);

   sp& operator = (const sp<T>& other);

   template<typename U> sp& operator = (const sp<U>&oth22er);

   template<typename U> sp& operator = (U* other);

    //Reset      

    voidclear();

    //Accessors 

   inline  T&     operator* () const  { return *m_ptr; }

   inline  T*      operator-> () const { returnm_ptr;  }      // 对“->”运算符进行重载

   inline  T*      get() const         { return m_ptr; }

private:

   template<typename Y> friend class sp;

   template<typename Y> friend class wp;

    //Optimization for wp::promote().

    sp(T*p, weakref_type* refs); 

    T*              m_ptr;

};

template<typename T>

sp<T>::sp(T* other)                                   // 构造函数參数为T类型指针

    :m_ptr(other)

{

    if(other) other->incStrong(this);                    //当创建sp对象时,添加强引用计数

}

template<typename T>

sp<T>::sp(const sp<T>& other)                          // 构造函数參数为T类型引用对象

    :m_ptr(other.m_ptr)

{

    if(m_ptr) m_ptr->incStrong(this);

}

template<typename T>

sp<T>::~sp()

{

    if(m_ptr) m_ptr->decStrong(this);                  //当析构sp对象时。降低强引用计数

}

template<typename T>

 sp<T>& sp<T>::operator = (T*other)                 // 对“=”运算符进行重载

 {

     if(other) other->incStrong(this);                   //添加other对象强引用计数

     if(m_ptr) m_ptr->decStrong(this);                //降低sp对象持有的旧对象强引用计数

     m_ptr= other;                                   //将other对象保存到sp对象中

    return *this;

 }

由sp类的定义可知。sp被定义为模板类。它拥有一个T指针类型的属性m_ptr,当创建sp对象时。将T类型指针或T类型引用赋值给m_ptr,同一时候调用m_ptr的incStrong方法来添加引用计数,由此可见。m_ptr的T类型应该是LightRefBase的子类。它就是我们要进行管理的目标对象。当sp对象生命周期结束时。会调用它的析构函数~sp,析构函数中调用m_ptr的decStrong的来降低强引用计数,当引用计数减为0时将目标对象delete。

sp类对“->”运算符进行了重载,当sp对象使用运算符“->”时。返回m_ptr指针。这样相当于“T->成员”訪问。通过运算符重载将sp对象操作转化成了T对象操作,保证了LightRefBase子类能訪问到自己的成员。

sp类还对“=”运算符进行了重载,将一个T指针类型other作为“=”右值时,首先会添加other对象的强引用计数。降低sp之前引用对象的强引用计数。然后再将other对象保存在m_ptr中,从而让sp对象指向新的对象other。

 

我们能够总结出,在Android轻量级智能指针实现中有下面规定:

l LightRefBase类(或其子类)的对象能够通过智能指针sp进行管理

l 当使用智能指针sp指向、赋值、初始化LightRefBase对象时,该对象引用计数加1。

l 当sp指针使用完后,其指向的对象引用计数自己主动减1。

l 当LightRefBase对象的引用计数为0时,该对象会被delete。

通过对Android轻量级指针类LightRefBase和智能指针类sp代码分析可知。Android中定义的这套智能指针,能够简单有效的对Android本地对象进行管理。提高代码的编写效率。在Android系统中。除了轻量级智能指针外,还有支持强指针(Strong Pointer)和弱指针(WeakPointer)的RefBase重量级指针类。

5.3 RefBase

         RefBase类的定义还是比較复杂的。它里面并没有我们预想中的计数变量的直接定义。而是将计数放在了一个叫weak_impl的类中进行封装。

         RefBase类中不仅仅定义了mStrong强引用计数。而且另一个mWeak的弱引用计数,强引用计数主要被sp对象管理。弱引用计数主要被wp对象管理。

RefBase的定义简化代码例如以下:

@frameworks/base/include/utils/RefBase.h

class RefBase

{

public

           void            incStrong(constvoid* id) const;

           void            decStrong(constvoid* id) const;

     classweakref_type

     {

    public:

        RefBase*       refBase() const;

        void                incWeak(constvoid* id);

        void                decWeak(constvoid* id);

     };

 protected:

                             RefBase();

    virtual              ~RefBase();

     enum{

        OBJECT_LIFETIME_WEAK    = 0x0001,             // 目标对象受弱引用计数影响标志

        OBJECT_LIFETIME_FOREVER = 0x0003              //目标对象不受强、弱引用计数影响标志

     };

    virtual void       onFirstRef();

    virtual void      onLastStrongRef(const void* id);

    virtual void      onLastWeakRef(const void* id); 

private:

    friend class weakref_type;

     classweakref_impl;

    weakref_impl* const mRefs; 

 };

RefBase::RefBase()                                   // 构造函数,创建weakref_impl对象赋值给mRefs

    :mRefs(new weakref_impl(this))

{

//   LOGV("Creating refs %p with RefBase %p ", mRefs, this);

}

RefBase::~RefBase()                                 // 析构函数,当弱引用计数减为0时,删除mRefs指向的对象

{

//   LOGV("Destroying RefBase %p (refs %p) ", this, mRefs);

    if(mRefs->mWeak == 0) {

//       LOGV("Freeing refs %p of old RefBase %p ", mRefs, this);

       delete mRefs;

    }

}

void RefBase::incStrong(const void* id) const     // 添加强引用计数

{

   weakref_impl* const refs = mRefs;

   refs->addWeakRef(id);

   refs->incWeak(id);                               //先添加弱引用计数

   refs->addStrongRef(id);                       //再添加弱引用计数

    constint32_t c = android_atomic_inc(&refs->mStrong);

   LOG_ASSERT(c > 0, "incStrong() called on %p after last strongref", refs);

#if PRINT_REFS

   LOGD("incStrong of %p from %p: cnt=%d ", this, id, c);

#endif

    if (c!= INITIAL_STRONG_VALUE)  {

       return;

    }

   android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);

   const_cast<RefBase*>(this)->onFirstRef();    // 当第一次强引用时调用onFirstRef接口

}

void RefBase::decStrong(const void* id) const

{

   weakref_impl* const refs = mRefs;

   refs->removeStrongRef(id);

    constint32_t c = android_atomic_dec(&refs->mStrong);  // 降低强引用计数

#if PRINT_REFS

   LOGD("decStrong of %p from %p: cnt=%d ", this, id, c);

#endif

   LOG_ASSERT(c >= 1, "decStrong() called on %p too manytimes", refs);

    if (c== 1) {

       const_cast<RefBase*>(this)->onLastStrongRef(id);  // 当最后一次强引用对象时回调onLastStrongRef

        if((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {

           delete this;                                      //当目标对象生命周期不受弱引用计数影响时,删除目标对象

        }

    }

   refs->removeWeakRef(id);

   refs->decWeak(id);

}

当中。在构造RefBase类时。创建了一个weakref_impl对象,它用来封装强、弱引用计数变量和目标对象影响标记。它是weakref_type的子类。

class RefBase::weakref_impl : public RefBase::weakref_type

{

public:

   volatile int32_t    mStrong;                // 强引用计数变量

   volatile int32_t    mWeak;                 // 弱引用计数变量

   RefBase* const      mBase;

volatileint32_t    mFlags;            // 目标对象是否受引用计数标志变量

   Destroyer*          mDestroyer;

#if !DEBUG_REFS

   weakref_impl(RefBase* base)

        :mStrong(INITIAL_STRONG_VALUE)

        ,mWeak(0)

        ,mBase(base)

        , mFlags(0)      //初始化为0,即不是OBJECT_LIFETIME_WEAK。也不是OBJECT_LIFETIME_FOREVER

        ,mDestroyer(0)

    {

    }

虚函数onFirstRef、onLastStrongRef、onLastWeakRef能够在子类中实现,当RefBase的子类对象被第一次强引用、最后一次强引用、最后一次弱引用时被回调,onFirstRef函数主要用来在Android对象创建时做一些初始化操作,onLastStrongRef用来在Android对象销毁前做一些“收尾“工作。

 

RefBase里incStrong和decStrong用来添加强引用计数。incStrong添加强引用计数同一时候添加弱引用计数,在decStrong中,降低强引用计数,假设在强引用计数变为0。而且目标对象标记为非OBJECT_LIFETIME_WEAK(目标对象生命周期不受弱引用计数影响),删除目标对象。

依据面向对象继承原理,仅仅要我们的类继承RefBase类,那么这个子类就拥有更强的“自己主动管理对象能力”。同一时候它还能够让子类对象通过覆盖onXXXRef方法实如今对象创建时和销毁时完毕特定功能的能力。

 

尽管RefBase类提供了强弱引用计数和相应的操作接口,为了实现智能管理对象,通常我们一般不须要手动调用强弱引用操作接口,真正对计数进行操作的是强指针引用对象 sp和弱引用计数wp对象。

l sp强指针对象:

sp对象能够通过“->”执行符直接訪问目标对象成员,而且直接管理着目标对象的销毁

l wp弱指针对象:

wp表示对一个目标对象的弱引用。它不能直接訪问目标对象成员,仅仅表示两者间存在引用关系。假设wp想訪问目标对象。则必须由弱引用升级成强引用。

使用sp和wp有下面规定:

l RefBase对象中有一个隐含的对象mRefs,该对象内部有强弱引用计数

l RefBase类(或其子类)的对象能够通过sp和wp对象进行管理

l 当目标对象被sp引用时。表示对目标对象强引用。其强、弱引用计数各加1。

l 当目标对象被wp引用时,表示对目标对象弱引用。其弱引用计数加1。

l 目标对象的生死由weakref_impl.mFlags和引用类型决定:

n 当目标对象weakref_impl.mFlags标记为OBJECT_LIFETIME_FOREVER时,对象不受强、弱引用计数影响。

n 当目标对象的强、弱引用计数为0且标记为OBJECT_LIFETIME_WEAK时,目标对象会被删除。

n 当目标对象的强引用计数为0而且标记为默认值0(非OBJECT_LIFETIME_WEAK和OBJECT_LIFETIME_FOREVER)时。该目标对象被delete。

在5.2节我们已经分析过sp的实现代码,它通过运算符重载、拷贝构造函数、构造函数、析构函数机制实现了目标对象指针的赋值、引用等操作。

我们来看使用sp的样例:

我们先创建RefBase的子类RefTest.cpp:

#include <stdio.h>

#include <utils/RefBase.h>

using namespace android;

class RefTest: public RefBase

{

public:

RefTest ()

        {

               printf("Construct RefTest Object. ");

        }

       virtual ~RefTest ()

        {

               printf("Destory RefTest Object. ");

        }

};

int main(int argc, char** argv)

{

RefTest * pRefTest = new RefTest ();

       sp<RefTest>spRefTest = pRefTest;

       printf("Ref Count: %d. ", pRefTest->getStrongCount());

        {

               sp<RefTest>spInner = pRefTest;

               printf("Ref Count: %d. ", RefTest->getStrongCount());

        }

        printf("Ref Count: %d. ", RefTest->getStrongCount());

       return 0;

}

我们首先定义了一个类RefTest它继承了RefBase,在RefTest中的构造函数和析构函数中仅打印一句话。在main函数中首先创建一个RefTest类的堆对象pRefTest,然后声明强引用对象spRefTest,模板类型为RefTest。

依据RefBase中对“=”执行符重载可知,将pRefTest赋值给spRefTest时,会添加pRefTest强引用计数,打印出当前强引用计数。然后在“{}”内再次将RefTest对象赋值给强引用对象spInner。打印出强引用计数,“{}”内代码执行完毕,spInner对象销毁,这时在~sp析构函数内自己主动将对RefTest对象强引用计数减1。

再次打印强引用计数值。

要想查看上述代码的执行结果。依据第四章内容可知。我们必须要编写一个Android.mk文件:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=

        RefTest.cpp

LOCAL_SHARED_LIBRARIES :=

       libcutils

       libutils

LOCAL_MODULE:= RefTest

include $(BUILD_EXECUTABLE)

在Android.mk中指定用到的两个库:libcutils(Android中的C库)和libutils(RefBase所在的库),然后将RefTest.cpp编译成应用程序执行。

编译代码(RefTestproject放在xxx文件夹下):

$ mmm device/farsight/chapter5/RefTest

生成新的Android映像:

$ make snod

执行结果例如以下:

# RefTest

Construct RefTest Object.

Ref Count: 1.

Ref Count: 2.

Ref Count: 1.

Destory RefTest Object.

由执行结果可清楚看到,强引用计数随着sp所持有次数在改变,我们总结例如以下:

l 要想对Android本地对象进行智能管理。该对象必须是RefBase的子类对象

l 本地对象必须结合sp对象来联合使用,sp实现了对强引用计数的自己主动管理

因为强引用计数决定了本地对象的生死。所以sp用来持有必须依赖的对象

5.2 弱引用指针wp

弱引用指针wp表示对一个目标对象的弱引用关系。它不能和sp一样直接訪问目标对象成员,假设wp想訪问目标对象。则必须由弱引用升级成强引用。

弱引用wp的实现代码:

@frameworks/base/include/utils/RefBase.h

template <typename T>

class wp

{

public:

   typedef typename RefBase::weakref_type weakref_type;

    inlinewp() : m_ptr(0) { }

    wp(T*other);

   wp(const wp<T>& other);

   wp(const sp<T>& other);

   template<typename U> wp(U* other);

   template<typename U> wp(const sp<U>& other);

   template<typename U> wp(const wp<U>& other);

    ~wp();

    //Assignment

   wp& operator = (T* other);

   wp& operator = (const wp<T>& other);

   wp& operator = (const sp<T>& other);

   template<typename U> wp& operator = (U* other);

   template<typename U> wp& operator = (const wp<U>&other);

   template<typename U> wp& operator = (const sp<U>&other);

voidset_object_and_refs(T* other, weakref_type* refs);

    //promotion to sp

sp<T>promote() const;

voidclear();

private:

   template<typename Y> friend class sp;

   template<typename Y> friend class wp;

    T*              m_ptr;

weakref_type*   m_refs;

};

通过代码可知,在wp中持有T类型指针m_ptr和weakref_type类型指针m_refs。通过构造函数能够看出,它能够接收wp和sp引用或指针来构造新wp对象,在wp中定义一个promote函数,它用来将一个弱引用升级为强引用。wp也重载了“=”运算符,可是没有实现运算符“->”、“*”,说明我们能够为wp赋值。而不能通过wp直接訪问目标对象。wp还实现了clear方法。该方法用来清除弱引用指针,降低对实际对象的弱引用计数。将m_ptr指针清空。

template<typename T>

wp<T>::wp(const wp<T>& other)                // 拷贝构造函数,接收弱引用

    :m_ptr(other.m_ptr), m_refs(other.m_refs)

{

    if(m_ptr) m_refs->incWeak(this);

}

template<typename T>

wp<T>::~wp()

{

    if(m_ptr) m_refs->decWeak(this);

}

template<typename T>

wp<T>& wp<T>::operator = (constsp<T>& other)         // “=”执行符重载

{

   weakref_type* newRefs =

       other != NULL ? other->createWeak(this) : 0;

    if(m_ptr) m_refs->decWeak(this);

    m_ptr= other.get();

    m_refs= newRefs;

    return*this;

}

template<typename T>

voidsp<T>::clear()

{

    if(m_ptr) {

       m_ptr->decWeak(this);

       m_ptr = 0;

    }

}

当wp对象创建或赋值时,都会添加弱引用计数,当wp析构时。调用decWeak函数降低引用计数。当弱引用计数等于1时,要依据impl->mFlags标记来决定,当mFlags为OBJECT_LIFETIME_WEAK时,表示目标对象生命周期受弱引用计数影响。回调onLastWeakRef方法,而且delete目标对象,当mFlags为OBJECT_LIFETIME_FOREVER。说明目标对象生命周期不受引用计数影响,目标对象永远不能被删除。

@frameworks/base/libs/utils/RefBase.cpp

void RefBase::weakref_type::incWeak(const void*id)                      

{

   weakref_impl* const impl = static_cast<weakref_impl*>(this);

   impl->addWeakRef(id);

    constint32_t c = android_atomic_inc(&impl->mWeak);    // Android自己实现的原子添加计数

   LOG_ASSERT(c >= 0, "incWeak called on %p after last weakref", this);

}

void RefBase::weakref_type::decWeak(const void*id)

{

   weakref_impl* const impl = static_cast<weakref_impl*>(this);

   impl->removeWeakRef(id);

    constint32_t c = android_atomic_dec(&impl->mWeak);   // 降低弱引用计数

   LOG_ASSERT(c >= 1, "decWeak called on %p too many times",this);

    if (c!= 1) return;                                            //当弱引用计数 !=1 时,直接返回

    if((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {

        if(impl->mStrong == INITIAL_STRONG_VALUE)                //标记为INITIAL_STRONG_VALUE

           delete impl->mBase;                                 // 释放RefBase对象

       else {

//           LOGV("Freeing refs %p of old RefBase %p ", this,impl->mBase);

           delete impl;                                              //释放内置的weakref_type对象

        }

    } else{                                                //标记为OBJECT_LIFETIME_WEAK

       impl->mBase->onLastWeakRef(id);                          

        if((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {

           delete impl->mBase;                                 //标记为非OBJECT_LIFETIME_FOREVER时

                                                        //仅仅释放RefBase对象

        }

    }

}

5.3 智能指针的演示样例

在Android系统中硬件资源通常被共享使用,如摄像头、传感器、Wifi等。

这些硬件资源通常被封装成Service用于向其他使用者提供硬件服务,这些使用者被称为Client。

在Android应用程序中可能同一时候多个应用程序使用同一硬件资源。即:可能存在多个Client要訪问Service。

在Service中维护这些Client对象往往使用智能指针来控制。我们以摄像头为例来说明。

摄像头的Service为CameraService封装类,其定义例如以下:

@frameworks/base/services/camera/libcameraservice/CameraService.h

class CameraService :publicBinderService<CameraService>,public BnCameraService

 {

         ……

private:

wp<Client>          mClient[MAX_CAMERAS];

         ……

classClient : public BnCamera

         {……}

}

在CameraService中定义了一个对象数组mClient,其成员为Client对象的wp弱引用类型指针。即:该对象并不决定实际对象的生死(mFlags为默认值)。

它主要用于服务端保持对连接客户端对象地址,当Android应用程序訪问CameraService时,调用Connect方法来保持和Service的连接进行通信。

@frameworks/base/services/camera/libcameraservice/CameraService.cpp

sp<ICamera> CameraService::connect(constsp<ICameraClient>& cameraClient, int cameraId) {

         …

sp<Client>client;

if(mClient[cameraId] != 0) {

client = mClient[cameraId].promote();

         …

         returnNULL;

                 }

client= new Client(this, cameraClient, hardware, cameraId, info.facing,callingPid);

mClient[cameraId]= client;

         returnclient;

}

在Connect方法内首先推断client对象是否存在,假设存在说明该Client正在和Service进行通信。返回NULL。假设client对象不存在,创建了Client对象。使用sp保持对该对象的强引用,同一时候将Client对象的wp弱引用保存在mClient数组中,sp强引用client在当前方法使用完后被析构,其对象被智能指针管理。

当我们想使用某个Client对象时,仅仅须要提供其cameraID就可以,假设该Client对象已经被智能指针释放,可是因为wp指针数组mClient还维持着弱引用,能够调用弱引用的promote来进行“由弱升强”将对象又一次创建并使用。

sp<CameraService::Client>CameraService::getClientById(int cameraId) {

if(cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;

returnmClient[cameraId].promote();

}

当Android应用程序不在使用CameraService时,调用removeClient来释放指定的连接。

void CameraService::removeClient(constsp<ICameraClient>& cameraClient) {

for(int i = 0; i < mNumberOfCameras; i++) {         // 循环遍历全部的客户端连接对象

                   sp<Client>client;   

                   if(mClient[i] == 0) continue;

                   client= mClient[i].promote();             // 由弱转强

   if (client == 0) {                              //假设强引用对象为空

                            mClient[i].clear();            // 删除对Client对象的弱引用

                            continue;

                   }

                   if(cameraClient->asBinder() == client->getCameraClient()->asBinder()) {  // 假设是指定的待释放连接

                            mClient[i].clear();                   //删除对Client对象的弱引用

                            break;

                   }

         }

}

智能指针使用要点:

l Android中智能指针分为:轻量级LightRefBase和重量级RefBase。LightRefBase仅仅能使用sp指针,主要用于简单的管理一些全局对象的自己主动释放。通经常使用于简单逻辑处理,而RefBase相对来说功能更强大,不仅仅通过sp指针决定对象生命周期。还能够通过wp指针来维持对象的引用关系,通过“由弱升强”来訪问对象成员。而且RefBase能够通过设置mFlags来限制智能指针对实际对象生命周期的影响。

l 智能指针能够管理的对象必须是LightRefBase或RefBase的子类对象。

l 当使用智能指针管理对象时,不要试图通过delete手动删除实际对象。


原文地址:https://www.cnblogs.com/brucemengbm/p/6710200.html