版权声明:本文为博主原创文章,未经博主允许不得转载。
转载请标明出处:
http://blog.youkuaiyun.com/lmj623565791/article/details/47017485;
本文出自:【张鸿洋的博客】
一、概述
说到Android进程间通信,大家肯定能想到的是编写aidl文件,然后通过aapt生成的类方便的完成服务端,以及客户端代码的编写。如果你对这个过程不熟悉,可以查看Android aidl Binder框架浅析;
当然今天要说的通信方式肯定不是通过编写aidl文件的方式,那么有请今天的主角:Messenger
。ok,这是什么样的一个类呢?我们看下注释
This allows for the implementation of message-based communication across processes
允许实现基于消息的进程间通信的方式。
那么,什么叫基于消息的进程间通信方式呢?看个图理解下:
可以看到,我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。
这样的进程间通信是不是很爽呢?
- 基于Message,相信大家都很熟悉
- 支持回调的方式,也就是服务端处理完成长任务可以和客户端交互
- 不需要编写aidl文件
此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信,这个后面再说。
看到这,有没有一些的小激动,我们可以不写aidl文件,方便的实现进程间通信了,是不是又可以装一下了。哈,下面看个简单的例子。
二、通信实例
这个例子,通过两个apk演示,一个apk是Server端,一个是Client端;
(1) Server端
代码
<code class="language-java hljs has-numbering"><span class="hljs-keyword">package</span> com.imooc.messenger_server; <span class="hljs-keyword">import</span> android.app.Service; <span class="hljs-keyword">import</span> android.content.Intent; <span class="hljs-keyword">import</span> android.os.Handler; <span class="hljs-keyword">import</span> android.os.IBinder; <span class="hljs-keyword">import</span> android.os.Message; <span class="hljs-keyword">import</span> android.os.Messenger; <span class="hljs-keyword">import</span> android.os.RemoteException; <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MessengerService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Service</span> {</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> MSG_SUM = <span class="hljs-number">0x110</span>; <span class="hljs-comment">//最好换成HandlerThread的形式</span> <span class="hljs-keyword">private</span> Messenger mMessenger = <span class="hljs-keyword">new</span> Messenger(<span class="hljs-keyword">new</span> Handler() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleMessage</span>(Message msgfromClient) { Message msgToClient = Message.obtain(msgfromClient);<span class="hljs-comment">//返回给客户端的消息</span> <span class="hljs-keyword">switch</span> (msgfromClient.what) { <span class="hljs-comment">//msg 客户端传来的消息</span> <span class="hljs-keyword">case</span> MSG_SUM: msgToClient.what = MSG_SUM; <span class="hljs-keyword">try</span> { <span class="hljs-comment">//模拟耗时</span> Thread.sleep(<span class="hljs-number">2000</span>); msgToClient.arg2 = msgfromClient.arg1 + msgfromClient.arg2; msgfromClient.replyTo.send(msgToClient); } <span class="hljs-keyword">catch</span> (InterruptedException e) { e.printStackTrace(); } <span class="hljs-keyword">catch</span> (RemoteException e) { e.printStackTrace(); } <span class="hljs-keyword">break</span>; } <span class="hljs-keyword">super</span>.handleMessage(msgfromClient); } }); <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> IBinder <span class="hljs-title">onBind</span>(Intent intent) { <span class="hljs-keyword">return</span> mMessenger.getBinder(); } } </code>
服务端就一个Service,可以看到代码相当的简单,只需要去声明一个Messenger
对象,然后onBind方法返回mMessenger.getBinder();
然后坐等客户端将消息发送到handleMessage想法,根据message.what去判断进行什么操作,然后做对应的操作,最终将结果通过 msgfromClient.replyTo.send(msgToClient);返回。
可以看到我们这里主要是取出客户端传来的两个数字,然后求和返回,这里我有意添加了sleep(2000)模拟耗时,注意在实际使用过程中,可以换成在独立开辟的线程中完成耗时操作,比如和HandlerThread结合使用。
注册文件
<code class="language-xml hljs has-numbering"> <span class="hljs-tag"><<span class="hljs-title">service </span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">".MessengerService"</span> <span class="hljs-attribute">android:enabled</span>=<span class="hljs-value">"true"</span> <span class="hljs-attribute">android:exported</span>=<span class="hljs-value">"true"</span>></span> <span class="hljs-tag"><<span class="hljs-title">intent-filter</span>></span> <span class="hljs-tag"><<span class="hljs-title">action</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"com.zhy.aidl.calc"</span>></span><span class="hljs-tag"></<span class="hljs-title">action</span>></span> <span class="hljs-tag"><<span class="hljs-title">category</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.intent.category.DEFAULT"</span> /></span> <span class="hljs-tag"></<span class="hljs-title">intent-filter</span>></span> <span class="hljs-tag"></<span class="hljs-title">service</span>></span></code>
别忘了注册service,写完以后直接安装。
(二)客户端
Activity
<code class="language-java hljs has-numbering"><span class="hljs-keyword">package</span> com.imooc.messenger_client; <span class="hljs-keyword">import</span> android.content.ComponentName; <span class="hljs-keyword">import</span> android.content.Context; <span class="hljs-keyword">import</span> android.content.Intent; <span class="hljs-keyword">import</span> android.content.ServiceConnection; <span class="hljs-keyword">import</span> android.os.Bundle; <span class="hljs-keyword">import</span> android.os.Handler; <span class="hljs-keyword">import</span> android.os.IBinder; <span class="hljs-keyword">import</span> android.os.Message; <span class="hljs-keyword">import</span> android.os.Messenger; <span class="hljs-keyword">import</span> android.os.RemoteException; <span class="hljs-keyword">import</span> android.support.v7.app.AppCompatActivity; <span class="hljs-keyword">import</span> android.util.Log; <span class="hljs-keyword">import</span> android.view.View; <span class="hljs-keyword">import</span> android.widget.Button; <span class="hljs-keyword">import</span> android.widget.LinearLayout; <span class="hljs-keyword">import</span> android.widget.TextView; <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> {</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String TAG = <span class="hljs-string">"MainActivity"</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> MSG_SUM = <span class="hljs-number">0x110</span>; <span class="hljs-keyword">private</span> Button mBtnAdd; <span class="hljs-keyword">private</span> LinearLayout mLyContainer; <span class="hljs-comment">//显示连接状态</span> <span class="hljs-keyword">private</span> TextView mTvState; <span class="hljs-keyword">private</span> Messenger mService; <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> isConn; <span class="hljs-keyword">private</span> Messenger mMessenger = <span class="hljs-keyword">new</span> Messenger(<span class="hljs-keyword">new</span> Handler() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleMessage</span>(Message msgFromServer) { <span class="hljs-keyword">switch</span> (msgFromServer.what) { <span class="hljs-keyword">case</span> MSG_SUM: TextView tv = (TextView) mLyContainer.findViewById(msgFromServer.arg1); tv.setText(tv.getText() + <span class="hljs-string">"=>"</span> + msgFromServer.arg2); <span class="hljs-keyword">break</span>; } <span class="hljs-keyword">super</span>.handleMessage(msgFromServer); } }); <span class="hljs-keyword">private</span> ServiceConnection mConn = <span class="hljs-keyword">new</span> ServiceConnection() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onServiceConnected</span>(ComponentName name, IBinder service) { mService = <span class="hljs-keyword">new</span> Messenger(service); isConn = <span class="hljs-keyword">true</span>; mTvState.setText(<span class="hljs-string">"connected!"</span>); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onServiceDisconnected</span>(ComponentName name) { mService = <span class="hljs-keyword">null</span>; isConn = <span class="hljs-keyword">false</span>; mTvState.setText(<span class="hljs-string">"disconnected!"</span>); } }; <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> mA; <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) { <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); setContentView(R.layout.activity_main); <span class="hljs-comment">//开始绑定服务</span> bindServiceInvoked(); mTvState = (TextView) findViewById(R.id.id_tv_callback); mBtnAdd = (Button) findViewById(R.id.id_btn_add); mLyContainer = (LinearLayout) findViewById(R.id.id_ll_container); mBtnAdd.setOnClickListener(<span class="hljs-keyword">new</span> View.OnClickListener() { <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(View v) { <span class="hljs-keyword">try</span> { <span class="hljs-keyword">int</span> a = mA++; <span class="hljs-keyword">int</span> b = (<span class="hljs-keyword">int</span>) (Math.random() * <span class="hljs-number">100</span>); <span class="hljs-comment">//创建一个tv,添加到LinearLayout中</span> TextView tv = <span class="hljs-keyword">new</span> TextView(MainActivity.<span class="hljs-keyword">this</span>); tv.setText(a + <span class="hljs-string">" + "</span> + b + <span class="hljs-string">" = caculating ..."</span>); tv.setId(a); mLyContainer.addView(tv); Message msgFromClient = Message.obtain(<span class="hljs-keyword">null</span>, MSG_SUM, a, b); msgFromClient.replyTo = mMessenger; <span class="hljs-keyword">if</span> (isConn) { <span class="hljs-comment">//往服务端发送消息</span> mService.send(msgFromClient); } } <span class="hljs-keyword">catch</span> (RemoteException e) { e.printStackTrace(); } } }); } <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">bindServiceInvoked</span>() { Intent intent = <span class="hljs-keyword">new</span> Intent(); intent.setAction(<span class="hljs-string">"com.zhy.aidl.calc"</span>); bindService(intent, mConn, Context.BIND_AUTO_CREATE); Log.e(TAG, <span class="hljs-string">"bindService invoked !"</span>); } <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onDestroy</span>() { <span class="hljs-keyword">super</span>.onDestroy(); unbindService(mConn); } } </code>
代码也不复杂,首先bindService,然后在onServiceConnected中拿到回调的service(IBinder)对象,通过service对象去构造一个mService =new Messenger(service);
然后就可以使用mService.send(msg)给服务端了。
我们消息的发送在Btn.onclick里面:
<code class="language-java hljs has-numbering">Message msgFromClient = Message.obtain(<span class="hljs-keyword">null</span>, MSG_SUM, a, b); msgFromClient.replyTo = mMessenger; <span class="hljs-keyword">if</span> (isConn) { <span class="hljs-comment">//往服务端发送消息</span> mService.send(msgFromClient); } </code>
那么服务端会收到消息,处理完成会将结果返回,传到Client端的mMessenger中的Handler的handleMessage方法中。
布局文件
<code class="language-xml hljs has-numbering"><span class="hljs-tag"><<span class="hljs-title">LinearLayout</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_ll_container"</span> <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute">xmlns:tools</span>=<span class="hljs-value">"http://schemas.android.com/tools"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:orientation</span>=<span class="hljs-value">"vertical"</span> <span class="hljs-attribute">android:paddingBottom</span>=<span class="hljs-value">"@dimen/activity_vertical_margin"</span> <span class="hljs-attribute">android:paddingLeft</span>=<span class="hljs-value">"@dimen/activity_horizontal_margin"</span> <span class="hljs-attribute">android:paddingRight</span>=<span class="hljs-value">"@dimen/activity_horizontal_margin"</span> <span class="hljs-attribute">android:paddingTop</span>=<span class="hljs-value">"@dimen/activity_vertical_margin"</span> <span class="hljs-attribute">tools:context</span>=<span class="hljs-value">".MainActivity"</span>></span> <span class="hljs-tag"><<span class="hljs-title">TextView </span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_tv_callback"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"Messenger Test!"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">Button</span> <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/id_btn_add"</span> <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"wrap_content"</span> <span class="hljs-attribute">android:text</span>=<span class="hljs-value">"add"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">LinearLayout</span>></span> </code>
效果图
可以看到,我们每点击一次按钮,就往服务器发送个消息,服务器拿到消息执行完成后,将结果返回。
整个通信的代码看起来还是相当的清爽的,那么大家有没有对其内部的原理有一丝的好奇呢?下面我们就来看下其内部是如何实现的。
对了,源码分析前,这里插一句,大家通过代码可以看到服务端往客户端传递数据是通过msg.replyTo这个对象的。那么服务端完全可以做到,使用一个List甚至Map去存储所有绑定的客户端的msg.replyTo对象,然后想给谁发消息都可以。甚至可以把A进程发来的消息,通过B进程的msg.replyTo发到B进程那里去。相关代码呢,可以参考官方的文档:service,注意下拉找:Remote Messenger Service Sample。
三、源码分析
其实Messenger的内部实现的,实际上也是依赖于aidl文件实现的。
(一)首先我们看客户端向服务端通信
服务端
服务端的onBind是这么写的:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> IBinder <span class="hljs-title">onBind</span>(Intent intent) { <span class="hljs-keyword">return</span> mMessenger.getBinder(); }</code>
那么点进去:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> IBinder <span class="hljs-title">getBinder</span>() { <span class="hljs-keyword">return</span> mTarget.asBinder(); }</code>
可以看到返回的是mTarget.asBinder();
mTarget是哪来的呢?
别忘了我们前面去构造mMessenger对象的代码:new Messenger(new Handler())
;
<code class="language-java hljs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-title">Messenger</span>(Handler target) { mTarget = target.getIMessenger(); }</code>
原来是Handler返回的,我们继续跟进去
<code class="language-xml hljs has-numbering"> final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; } } private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { msg.sendingUid = Binder.getCallingUid(); Handler.this.sendMessage(msg); } }</code>
mTarget是一个MessengerImpl对象,那么asBinder实际上是返回this,也就是MessengerImpl对象;
这是个内部类,可以看到继承自IMessenger.Stub,然后实现了一个send方法,该方法就是将接收到的消息通过 Handler.this.sendMessage(msg);发送到handleMessage方法。
看到这,大家有没有想到什么,难道不觉得extends IMessenger.Stub这种写法异常的熟悉么?
我们传统写aidl文件,aapt给我们生成什么,生成IXXX.Stub类,然后我们服务端继承IXXX.Stub实现接口中的方法。
没错,其实这里内部其实也是依赖一个aidl生成的类,这个aidl位于:frameworks/base/core/java/android/os/IMessenger.aidl
.
<code class="language-java hljs has-numbering"><span class="hljs-keyword">package</span> android.os; <span class="hljs-keyword">import</span> android.os.Message; <span class="hljs-javadoc">/**<span class="hljs-javadoctag"> @hide</span> */</span> oneway interface IMessenger { <span class="hljs-keyword">void</span> send(in Message msg); } </code>
看到这,你应该明白了,Messenger并没有什么神奇之处,实际上,就是依赖该aidl文件生成的类,继承了IMessenger.Stub类,实现了send方法,send方法中参数会通过客户端传递过来,最终发送给handler进行处理。这里不理解,请详细看下Android aidl Binder框架浅析;
客户端
客户端首先通过onServiceConnected拿到sevice(Ibinder)对象,这里没什么特殊的,我们平时的写法也是这样的,只不过我们平时会这么写:
IMessenger.Stub.asInterface(service)拿到接口对象进行调用;
而,我们的代码中是
mService = new Messenger(service);
跟进去,你会发现:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-title">Messenger</span>(IBinder target) { mTarget = IMessenger.Stub.asInterface(target); }</code>
soga,和我们平时的写法一模一样!
到这里就可以明白,客户端与服务端通信,实际上和我们平时的写法没有任何区别,通过编写aidl文件,服务端onBind利用Stub编写接口实现返回;客户端利用回调得到的IBinder对象,使用IMessenger.Stub.asInterface(target)拿到接口实例进行调用(内部实现,参考Android aidl Binder框架浅析)。
(2)服务端与客户端通信
那么,客户端与服务端通信的确没什么特殊的地方,我们完全也可以编写个类似的aidl文件实现;那么服务端是如何与客户端通信的呢?
还记得,客户端send方法发送的是一个Message,这个Message.replyTo指向的是一个mMessenger,我们在Activity中初始化的。
那么将消息发送到服务端,肯定是通过序列化与反序列化拿到Message对象,我们看下Message的反序列化的代码:
<code class="language-java hljs has-numbering"># Message <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">readFromParcel</span>(Parcel source) { what = source.readInt(); arg1 = source.readInt(); arg2 = source.readInt(); <span class="hljs-keyword">if</span> (source.readInt() != <span class="hljs-number">0</span>) { obj = source.readParcelable(getClass().getClassLoader()); } when = source.readLong(); data = source.readBundle(); replyTo = Messenger.readMessengerOrNullFromParcel(source); sendingUid = source.readInt(); }</code>
主要看replyTo,调用的是Messenger.readMessengerOrNullFromParcel
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Messenger <span class="hljs-title">readMessengerOrNullFromParcel</span>(Parcel in) { IBinder b = in.readStrongBinder(); <span class="hljs-keyword">return</span> b != <span class="hljs-keyword">null</span> ? <span class="hljs-keyword">new</span> Messenger(b) : <span class="hljs-keyword">null</span>; } <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">writeMessengerOrNullToParcel</span>(Messenger messenger, Parcel out) { out.writeStrongBinder(messenger != <span class="hljs-keyword">null</span> ? messenger.mTarget.asBinder() : <span class="hljs-keyword">null</span>); }</code>
通过上面的writeMessengerOrNullToParcel可以看到,它将客户端的messenger.mTarget.asBinder()对象进行了恢复,客户端的message.mTarget.asBinder()是什么?
客户端也是通过Handler创建的Messenger,于是asBinder返回的是:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-title">Messenger</span>(Handler target) { mTarget = target.getIMessenger(); } <span class="hljs-keyword">final</span> IMessenger getIMessenger() { <span class="hljs-keyword">synchronized</span> (mQueue) { <span class="hljs-keyword">if</span> (mMessenger != <span class="hljs-keyword">null</span>) { <span class="hljs-keyword">return</span> mMessenger; } mMessenger = <span class="hljs-keyword">new</span> MessengerImpl(); <span class="hljs-keyword">return</span> mMessenger; } } <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MessengerImpl</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">IMessenger</span>.<span class="hljs-title">Stub</span> {</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">send</span>(Message msg) { msg.sendingUid = Binder.getCallingUid(); Handler.<span class="hljs-keyword">this</span>.sendMessage(msg); } } <span class="hljs-keyword">public</span> IBinder <span class="hljs-title">getBinder</span>() { <span class="hljs-keyword">return</span> mTarget.asBinder(); } </code>
那么asBinder,实际上就是MessengerImpl extends IMessenger.Stub
中的asBinder了。
<code class="language-java hljs has-numbering"> #IMessenger.Stub <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> android.os.IBinder <span class="hljs-title">asBinder</span>() { <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; }</code>
那么其实返回的就是MessengerImpl对象自己。到这里可以看到message.mTarget.asBinder()其实返回的是客户端的MessengerImpl对象。
最终,发送给客户端的代码是这么写的:
<code class="language-java hljs has-numbering"> msgfromClient.replyTo.send(msgToClient); <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">send</span>(Message message) <span class="hljs-keyword">throws</span> RemoteException { mTarget.send(message); } </code>
这个mTarget实际上就是对客户端的MessengerImpl对象的封装,那么send(message)(屏蔽了transact/onTransact的细节),这个message最终肯定传到客户端的handler的handleMessage方法中。
好了,到此我们的源码分析就结束了~~
总结下:
- 客户端与服务端通信,利用的aidl文件,没什么特殊的
- 服务端与客户端通信,主要是在传输的消息上做了处理,让Messager.replyTo指向的客户端的Messenger,而Messenger又持有客户端的一个Binder对象(MessengerImpl)。服务端正是利用这个Binder对象做的与客户端的通信。
可以考虑自己编写aidl文件,实现下服务端对客户端的回调。