可爱的BpXXX-图

来源:互联网 发布:unity3d射击游戏视频 编辑:程序博客网 时间:2024/04/28 11:16

http://blog.csdn.net/myarrow/article/details/7053763

1. 说BpXXX(如BpMediaPlayer)可爱,是因为它总是默默无闻地工作做,且基本上不露面(有点害羞的样子),但却总是做着重要的工作,没有它你如何调用mediaserver中为你准备好的各种功能呢?有了它,我们告诉它要听流行的“伤不起”,它就帮你放。你说它是不是一个听话的孩子呢?老板是不是很喜欢这样的员工呢偷笑

2. 既然它如此重要,但又基本上不露面,这可太为难我们这些天天if else的兄弟了。因为要找它难,没找到它之前,对这些if else的理解就更难了。所以做人也不能太害羞了,否则害了自己也害了大家,当然像MediaPlayer这样过于高调也不好,啥事不做,只当一个传话筒,还哪么高调,天天到处叫,来调我吧,来用我吧微笑

3. 在上一篇文章《Android媒体播放器框架--图》中讲过,MediaPlayer在setDataSource中调用BpMediaPlayerService::create时创建了BpMediaPlayer,并把它保存在MediaPlayer的mPlayer中,以供后面的调用。

4. 本文重点分析这个BpMediaPlayer是如何创建出来的。下面不得不看代码了。

[cpp] view plaincopyprint?
  1. status_t MediaPlayer::setDataSource(  
  2.         const char *url, const KeyedVector<String8, String8> *headers)  
  3. {  
  4.     LOGV("setDataSource(%s)", url);  
  5.     status_t err = BAD_VALUE;  
  6.     if (url != NULL) {  
  7.   
  8.         const sp<IMediaPlayerService>& service(getMediaPlayerService());  
  9.   
  10.         if (service != 0) {  
  11.             //调用BpMediaPlayerService::create  
  12.             sp<IMediaPlayer> player(service->create(getpid(), this, url, headers));  
  13.   
  14.             //把新创建的BpMediaPlayer保存在MediaPlayer的成员变量mPlayer中  
  15.             err = setDataSource(player);  
  16.         }  
  17.     }  
  18.     return err;  
  19. }  

自从这个MediaPlayer有了这个mPlayer之后,什么事就叫mPlayer来做,自已就成了领导了。

5.这明明是返回的是IMediaPlayer,为什么偏说是BpMediaPlayer呢?其原因有二。

   1)得益于C++中,只要这个指针指向派生类的对象,可把它转换为基类的指针来保存,调用方法时,会执行对应派生类中的方法。

   2)先看看MediaPlayer的家族图谱:

    

现在有两个问题需要解答:

1)为什么说上面代码中创建的player为指向BpMediaPlayer的指针?

2)为什么说BpMediaPlayer中的mRemote为指向BpBinder的指针?

 

6. 为什么说上面代码中创建的player为指向BpMediaPlayer的指针

这个还是让代码自己来讲吧:

[cpp] view plaincopyprint?
  1. class BpMediaPlayerService: public BpInterface<IMediaPlayerService>  
  2. {  
  3. public:  
  4.     ...  
  5.     virtual sp<IMediaPlayer> create(  
  6.             pid_t pid, const sp<IMediaPlayerClient>& client,  
  7.             const char* url, const KeyedVector<String8, String8> *headers) {  
  8.         Parcel data, reply;  
  9.         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());  
  10.         data.writeInt32(pid);  
  11.         data.writeStrongBinder(client->asBinder());  
  12.         data.writeCString(url);  
  13.   
  14.         if (headers == NULL) {  
  15.             data.writeInt32(0);  
  16.         } else {  
  17.             // serialize the headers  
  18.             data.writeInt32(headers->size());  
  19.             for (size_t i = 0; i < headers->size(); ++i) {  
  20.                 data.writeString8(headers->keyAt(i));  
  21.                 data.writeString8(headers->valueAt(i));  
  22.             }  
  23.         }  
  24.         //通过Binder发送请求给MediaPlayerService  
  25.         remote()->transact(CREATE_URL, data, &reply);  
  26.         //这就是重点??? reply.readStrongBinder()); 的返回值为一个new的BpBinder  
  27.         return interface_cast<IMediaPlayer>(reply.readStrongBinder()); //返回值为一个new的BpMediaPlayer  
  28.     }  
  29.     ...  
  30. }  

interface_cast<IMediaPlayer>(reply.readStrongBinder());结果是什么呢? 是IMediaPlayer还是BpMediaPlayer?期待其中的答案...(让我轻轻地告诉你,它是一个BpMeidaPlayer)

 

看似简单的一行代码,其内容可不简单,因为它涉及一个又一个模板。好玩吧!

6.1 先看看其参数是什么东东...(先偷偷地告诉你,一个新new的BpBinder)

reply.readStrongBinder()代码如下:

[cpp] view plaincopyprint?
  1. sp<IBinder> Parcel::readStrongBinder() const  
  2. {  
  3.     sp<IBinder> val;  
  4.     unflatten_binder(ProcessState::self(), *this, &val);  
  5.     return val;  
  6. }  

没什么,再向下看,不是什么东东都可以向下看的,否则别人会骂的。

[cpp] view plaincopyprint?
  1. status_t unflatten_binder(const sp<ProcessState>& proc,  
  2.     const Parcel& in, sp<IBinder>* out)  
  3. {  
  4.     const flat_binder_object* flat = in.readObject(false);  
  5.       
  6.     if (flat) {  
  7.         switch (flat->type) {  
  8.             case BINDER_TYPE_BINDER:  
  9.                 *out = static_cast<IBinder*>(flat->cookie);  
  10.                 return finish_unflatten_binder(NULL, *flat, in);  
  11.             case BINDER_TYPE_HANDLE: //因为我们是Client,当然会调用这个  
  12.                 *out = proc->getStrongProxyForHandle(flat->handle);  
  13.                 return finish_unflatten_binder(  
  14.                     static_cast<BpBinder*>(out->get()), *flat, in);  
  15.         }          
  16.     }  
  17.     return BAD_TYPE;  
  18. }  

6.1.1 还是哪么简单,只有两行代码,可内容还是不简单,再深入一步,看看第一行代码out返回的是什么东东?

[cpp] view plaincopyprint?
  1. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
  2. {  
  3.     sp<IBinder> result;  
  4.   
  5.     AutoMutex _l(mLock);  
  6.   
  7.     handle_entry* e = lookupHandleLocked(handle);  
  8.   
  9.     if (e != NULL) {  
  10.         // We need to create a new BpBinder if there isn't currently one, OR we  
  11.         // are unable to acquire a weak reference on this current one.  See comment  
  12.         // in getWeakProxyForHandle() for more info about this.  
  13.         IBinder* b = e->binder;  
  14.         if (b == NULL || !e->refs->attemptIncWeak(this)) {  
  15.             //第一次调用肯定走这儿  
  16.             b = new BpBinder(handle);   
  17.             e->binder = b;  
  18.             if (b) e->refs = b->getWeakRefs();  
  19.             result = b;  
  20.         } else {  
  21.             // This little bit of nastyness is to allow us to add a primary  
  22.             // reference to the remote proxy when this team doesn't have one  
  23.             // but another team is sending the handle to us.  
  24.             result.force_set(b);  
  25.             e->refs->decWeak(this);  
  26.         }  
  27.     }  
  28.     return result;  
  29. }  

呵呵,终于看到了,这个返回的就是一个BpBinder,其handle为传入的handle.现在已经看到reply.readStrongBinder()的返回值为一个BpBinder,即interface_cast<IMediaPlayer>(reply.readStrongBinder());的参数为一个BpBinder.


6.1.2 返回值已经产生,第二行代码finish_unflatten_binder( static_cast<BpBinder*>(out->get()), *flat, in);做什么呢?

[cpp] view plaincopyprint?
  1. inline static status_t finish_unflatten_binder(  
  2.     BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)  
  3. {  
  4.     return NO_ERROR;  
  5. }  

啥事没干,而且游戏嘎然而止。至此,参数已经分析完成,其结果就是一个指向BpBinder的一个指针。

 

7. 看看interface_cast<IMediaPlayer>(reply.readStrongBinder())即interface_cast<IMediaPlayer>(BpBinder)做了些什么,且返回值是什么? 老规距,让代码自己说话。以下就要与模板打交道了。

 7.1 寻找asInterface的真身

[cpp] view plaincopyprint?
  1. template<typename INTERFACE>  
  2. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  3. {  
  4.     return INTERFACE::asInterface(obj);  
  5. }  

又是一很简单。还原后代码为:

[cpp] view plaincopyprint?
  1. inline sp<IMediaPlayer> interface_cast(const sp<IBinder>& obj)  
  2. {  
  3.     return IMediaPlayer::asInterface(obj);  
  4. }        

原来以刚new的BpBinder对象为参数,调用IMediaPlayer::asInterface,还不快进去看其中的代码...,你以为你想进就进啊,你以为你是谁,告诉你没地方可进,代码中没看到这个函数,怎么办呢。只能看看IMedialayer的定义了。其定义中发现这么一行代码:

[cpp] view plaincopyprint?
  1. class IMediaPlayer: public IInterface  
  2. {  
  3. public:  
  4.     DECLARE_META_INTERFACE(MediaPlayer);  
  5.     ...  
  6. }  


很显然这是一个宏,这个可以看看吧!

[cpp] view plaincopyprint?
  1. #define DECLARE_META_INTERFACE(INTERFACE)                               \  
  2.     static const String16 descriptor;                                   \  
  3.     static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        \  
  4.     virtual const String16& getInterfaceDescriptor() const;             \  
  5.     I##INTERFACE();                                                     \  
  6.     virtual ~I##INTERFACE();    


我终于明白了你,原来在这儿定义了这个一直找寻的IMedaiPlayer::asInterface,老办法,还原啊!

[cpp] view plaincopyprint?
  1. static const String16 descriptor;                                     
  2. static sp<IMediaPlayer> asInterface(const sp<IBinder>& obj);          
  3. virtual const String16& getInterfaceDescriptor() const;               
  4. IMediaPlayer();                                                       
  5. virtual ~IMediaPlayer();    


asInterface的定义是有了,实现呢? asInterface啊asInterface,你怎么这么喜欢折腾人呢? 原来还认为你的BpXXX很可爱,现在觉得有点狡猾了。没办法,谁叫我们是搞if esle的呢! 继续找啊,相信有定义就有实现。找啊找,找到一个有意思的东东IMPLEMENT_META_INTERFACE(INTERFACE, NAME),Search下,在IMediaPlayer发现了IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");此宏定义如下:

[cpp] view plaincopyprint?
  1. #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \  
  2.     const String16 I##INTERFACE::descriptor(NAME);                      \  
  3.     const String16& I##INTERFACE::getInterfaceDescriptor() const {      \  
  4.         return I##INTERFACE::descriptor;                                \  
  5.     }                                                                   \  
  6.     sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \  
  7.     {                                                                   \  
  8.         sp<I##INTERFACE> intr;                                          \  
  9.         if (obj != NULL) {                                              \  
  10.             intr = static_cast<I##INTERFACE*>(                          \  
  11.                 obj->queryLocalInterface(                               \  
  12.                         I##INTERFACE::descriptor).get());               \  
  13.             if (intr == NULL) {                                         \  
  14.                 intr = new Bp##INTERFACE(obj);                          \  
  15.             }                                                           \  
  16.         }                                                               \  
  17.         return intr;                                                    \  
  18.     }                                                                   \  
  19.     I##INTERFACE::I##INTERFACE() { }                                    \  
  20.     I##INTERFACE::~I##INTERFACE() { }       


还原之后为:

[cpp] view plaincopyprint?
  1.    const String16 IMediaPlayer::descriptor("android.media.IMediaPlayer");                        
  2.     const String16& IMediaPlayer::getInterfaceDescriptor() const {        
  3.         return IMediaPlayer::descriptor;                                  
  4.     }                                                                     
  5. <pre class="cpp" name="code">    sp<IMediaPlayer> IMediaPlayer::asInterface(const sp<IBinder>& obj)    
  6.     {                                                                     
  7.         sp<IMediaPlayer> intr;                                            
  8.         if (obj != NULL) {                                                
  9.             intr = static_cast<IMediaPlayer*>(                            
  10.                 obj->queryLocalInterface(                                 
  11.                         IMediaPlayer::descriptor).get());                 
  12.             if (intr == NULL) {                                           
  13.                 intr = new BpMediaPlayer(obj);                            
  14.             }                                                             
  15.         }                                                                 
  16.         return intr;                                                      
  17.     }                                                                     
  18.     IMediaPlayer::IMediaPlayer() { }                                      
  19.     IMediaPlayer::~IMediaPlayer() { }     </pre>  
  20. <pre></pre>  
  21. <p><span style="font-family: Arial; font-size: 18px;">终于有asInterface的实现了,急切的心情看看他都做了些什么,单独拿出来品品吧!</span></p>  
  22. <pre class="cpp" name="code">    sp<IMediaPlayer> IMediaPlayer::asInterface(const sp<IBinder>& obj)    
  23.     {                                                                     
  24.         sp<IMediaPlayer> intr;                                            
  25.         if (obj != NULL) {                                                
  26.             intr = static_cast<IMediaPlayer*>(                            
  27.                 obj->queryLocalInterface(                                 
  28.                         IMediaPlayer::descriptor).get());                 
  29.             if (intr == NULL) {                                           
  30.                 intr = new BpMediaPlayer(obj); //第一次肯定执行这儿                           
  31.             }                                                             
  32.         }                                                                 
  33.         return intr;                                                      
  34.     } </pre>  
  35. <p><span style="font-family: Arial; font-size: 18px;">看到intr = new BpMediaPlayer(obj),obj为刚创建的BpBinder, 看到没有,BpMediaPlayer(常说的BpXXX)以如此低调的方式登场,难怪我们一时找不到它。</span></p>  
  36. <p><span style="font-size: 18px;"></span><span style="font-family: Arial;"> </span></p>  
  37. <p><span style="font-family: Arial; font-size: 18px;">至此,已经很明确了,<span style="color: rgb(255, 0, 0);">interface_cast<IMediaPlayer>(reply.readStrongBinder());</span>的结果是上面创建的<span style="color: rgb(255, 0, 0);">BpMediaPlayer</span>.<img alt="大笑" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif"><img alt="大笑" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif"></span></p>  
  38. <p><span style="font-size: 18px;"></span><span style="font-family: Arial;"> </span></p>  
  39. <p><span style="font-family: Arial; font-size: 18px; color: rgb(255, 0, 0);">7.2 看看new BpMediaPlayer都做了些什么?</span></p>  
  40. <p>还是让代码自己讲吧!</p>  
  41. <pre class="cpp" name="code">    BpMediaPlayer(const sp<IBinder>& impl)  
  42.         : BpInterface<IMediaPlayer>(impl)  
  43.     {  
  44.     }</pre>  
  45. <p><br>  
  46. <span style="font-family: Arial; font-size: 18px;">impl为刚创建的BpBinder, 再看看BpInterface<IMediaPlayer>(impl)做了什么。</span></p>  
  47. <pre class="cpp" name="code">template<typename INTERFACE>  
  48. inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)  
  49.     : BpRefBase(remote)  
  50. {  
  51. }</pre>我的乖乖,又是一个模板,继续还原:  
  52. <pre></pre>  
  53. <pre class="cpp" name="code"><pre class="cpp" name="code">inline BpInterface<IMediaPlayer>::BpInterface(const sp<IBinder>& remote)  
  54.     : BpRefBase(remote)  
  55. {  
  56. }</pre><br>  
  57. 深入看看BpRefBase(remote)做了些什么?<pre class="cpp" name="code">BpRefBase::BpRefBase(const sp<IBinder>& o)  
  58.     : mRemote(o.get()), mRefs(NULL), mState(0)  
  59. {  
  60.     extendObjectLifetime(OBJECT_LIFETIME_WEAK);  
  61.   
  62.     if (mRemote) {  
  63.         mRemote->incStrong(this);           // Removed on first IncStrong().  
  64.         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.  
  65.     }  
  66. }</pre>Oh,my God, 把刚创建的BpBinder赋值给了BpRefBase中的mRemote,所以上面的图上说mRemote本质上是一个BpBinder.现在得到证实了。  
  67. <pre></pre>  
  68. <pre></pre>  
  69. <pre></pre>  
  70. <pre></pre>  
  71. <pre></pre>  
  72.   
  73. </pre>  
更多0


0 0
原创粉丝点击