我们知道,Android是靠Binder机制来实现进程间的通信,而上一篇文章中,我们利用AIDL,简单地从代码方面的角度讲解了在服务端中的Binder的存在形式,是以服务的实现存在的,而在客户端,则是以代理的形式,实现存在的只是一个关于服务端的Binder实现的引用。

理论上的东西我们要去学习掌握,但是也不能忽略了实际的动手能力,对吧。

今天,我们就一步一步地利用我们所了解地关于AIDL的知识来实现一个跨进程通信的例子。

在Android的上层应用中,每一个App都是一个单独的进程,所以,要实现跨进程通信,我们需要至少有2个进程,一个代表服务端,一个代表客户端,所以我们会创建2个项目,来分别代表服务端和客户端。

服务端是提供服务的,得先提供服务,才能让客户端来享受服务,对吧。

服务端

我们创建一个服务端的项目,然后创建我们的aidl文件,毕竟只是一个Demo,所以我先从简单入手,方法不要太多,就叫IDemoService.aidl, 如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1">
    </embed>
  </div>
</div>
- <span class="keyword">package</span> com.lms.service;

- 
- <span class="keyword">interface</span> IDemoService {

- <span class="keyword">void</span> invoke();

- }

我们将其放在com.lms.service的包名目录下,表明其是提供服务的,当我们编译一下项目之后,就会发现在gen目录下面同样的包名下,生成了一个IDemoService.java的文件,如下:

而其生成的IDemoService.java文件内容如下,跟上一篇文章中所展现的其实一样,就是一个Stub类和一个Proxy类,如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2">
    </embed>
  </div>
</div>
- <span class="comment">/*</span>

- <span class="comment"> * This file is auto-generated.  DO NOT MODIFY.</span>

- <span class="comment"> * Original file: F:\\workspace_android\\AidlDemoClient\\src\\com\\lms\\service\\IDemoService.aidl</span>

- <span class="comment"> */</span>

- <span class="keyword">package</span> com.lms.service;

- 
- <span class="keyword">public</span> <span class="keyword">interface</span> IDemoService <span class="keyword">extends</span> android.os.IInterface {

- <span class="comment">/** Local-side IPC implementation stub class. */</span>

- <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">abstract</span> <span class="keyword">class</span> Stub <span class="keyword">extends</span> android.os.Binder <span class="keyword">implements</span>

- com.lms.service.IDemoService {

- <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> java.lang.String DESCRIPTOR = <span class="string">&#8220;com.lms.service.IDemoService&#8221;</span>;

- 
- <span class="comment">/** Construct the stub at attach it to the interface. */</span>

- <span class="keyword">public</span> Stub() {

- <span class="keyword">this</span>.attachInterface(<span class="keyword">this</span>, DESCRIPTOR);

- }

- 
- <span class="comment">/**</span>

- <span class="comment">         * Cast an IBinder object into an com.lms.service.IDemoService</span>

- <span class="comment">         * interface, generating a proxy if needed.</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">static</span> com.lms.service.IDemoService asInterface(

- android.os.IBinder obj) {

- <span class="keyword">if</span> ((obj == <span class="keyword">null</span>)) {

- <span class="keyword">return</span> <span class="keyword">null</span>;

- }

- android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

- <span class="keyword">if</span> (((iin != <span class="keyword">null</span>) && (iin <span class="keyword">instanceof</span> com.lms.service.IDemoService))) {

- <span class="keyword">return</span> ((com.lms.service.IDemoService) iin);

- }

- <span class="keyword">return</span> <span class="keyword">new</span> com.lms.service.IDemoService.Stub.Proxy(obj);

- }

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> android.os.IBinder asBinder() {

- <span class="keyword">return</span> <span class="keyword">this</span>;

- }

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">boolean</span> onTransact(<span class="keyword">int</span> code, android.os.Parcel data,

- android.os.Parcel reply, <span class="keyword">int</span> flags)

- <span class="keyword">throws</span> android.os.RemoteException {

- <span class="keyword">switch</span> (code) {

- <span class="keyword">case</span> INTERFACE_TRANSACTION: {

- reply.writeString(DESCRIPTOR);

- <span class="keyword">return</span> <span class="keyword">true</span>;

- }

- <span class="keyword">case</span> TRANSACTION_invoke: {

- data.enforceInterface(DESCRIPTOR);

- <span class="keyword">this</span>.invoke();

- reply.writeNoException();

- <span class="keyword">return</span> <span class="keyword">true</span>;

- }

- }

- <span class="keyword">return</span> <span class="keyword">super</span>.onTransact(code, data, reply, flags);

- }

- 
- <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">class</span> Proxy <span class="keyword">implements</span> com.lms.service.IDemoService {

- <span class="keyword">private</span> android.os.IBinder mRemote;

- 
- Proxy(android.os.IBinder remote) {

- mRemote = remote;

- }

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> android.os.IBinder asBinder() {

- <span class="keyword">return</span> mRemote;

- }

- 
- <span class="keyword">public</span> java.lang.String getInterfaceDescriptor() {

- <span class="keyword">return</span> DESCRIPTOR;

- }

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> invoke() <span class="keyword">throws</span> android.os.RemoteException {

- android.os.Parcel _data = android.os.Parcel.obtain();

- android.os.Parcel _reply = android.os.Parcel.obtain();

- <span class="keyword">try</span> {

- _data.writeInterfaceToken(DESCRIPTOR);

- mRemote.transact(Stub.TRANSACTION_invoke, _data, _reply, <span class="number"></span>);

- _reply.readException();

- } <span class="keyword">finally</span> {

- _reply.recycle();

- _data.recycle();

- }

- }

- }

- 
- <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> TRANSACTION_invoke = (android.os.IBinder.FIRST_CALL_TRANSACTION + <span class="number"></span>);

- }

- 
- <span class="keyword">public</span> <span class="keyword">void</span> invoke() <span class="keyword">throws</span> android.os.RemoteException;

- }

既然已经通过aidl生成了这份接口文件,那么根据上一篇文章所讲的,我们接下来就要来实现服务端这边提供的服务了。

我们可以想到,当我们在使用Android中的服务接口的时候,当其需要与其他模块进行相互通信的时候,我们一般是会通过绑定的形式实现的,而通过此种形式的实现,我们都会实现一个Binder,比如我们之前音乐播放器的实现,如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_3">
    </embed>
  </div>
</div>
- <span class="keyword">class</span> NatureBinder <span class="keyword">extends</span> Binder{

- 
- <span class="comment">/**</span>

- <span class="comment">         * 唱吧,有人想听</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> startPlay(<span class="keyword">int</span> currentMusic, <span class="keyword">int</span> currentPosition){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 别唱了</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> stopPlay(){}

- <span class="comment">/**</span>

- <span class="comment">         * 后一首</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> toNext(){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 前一首</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> toPrevious(){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 有人改变模式了,我得把它记下来 </span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> changeMode(){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 告诉别人,你现在到底是顺序播放,还是随机乱弹</span>

- <span class="comment">         * MODE_ONE_LOOP = 1;</span>

- <span class="comment">         * MODE_ALL_LOOP = 2;</span>

- <span class="comment">         * MODE_RANDOM = 3;</span>

- <span class="comment">         * MODE_SEQUENCE = 4; </span>

- <span class="comment">         * @return</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">int</span> getCurrentMode(){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 告诉调用者,到底有没有在做事。。。</span>

- <span class="comment">         * @return</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">boolean</span> isPlaying(){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 要告诉调用者,当前播哪首歌了,歌多长啊</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> notifyActivity(){}

- 
- <span class="comment">/**</span>

- <span class="comment">         * 有人拖动Seekbar了,要告诉service去改变播放的位置</span>

- <span class="comment">         * @param progress</span>

- <span class="comment">         */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> changeProgress(<span class="keyword">int</span> progress){}

- }

在上面这种情况下,Service是与同一个进程中的其他线程或者模块进行通信的,而在我们这种跨进程的服务中是不是也可以类似自己去实现我们AIDL中的定义的Stub类呢?

因为Stub类也是继承Binder的,而Binder又是实现了IBinder接口的,所以可以在调用Service的onBinde方法的时候,就返回我们实现的服务呀,对吧。

所以我们自定义一个服务,就叫做DemoService,如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_4">
    </embed>
  </div>
</div>
- <span class="keyword">package</span> com.lms.service;

- 
- <span class="keyword">import</span> android.app.Service;

- <span class="keyword">import</span> android.content.Intent;

- <span class="keyword">import</span> android.os.IBinder;

- 
- <span class="keyword">public</span> <span class="keyword">class</span> DemoService <span class="keyword">extends</span> Service{

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> IBinder onBind(Intent intent) {

- <span class="comment">// TODO Auto-generated method stub</span>

- <span class="keyword">return</span> <span class="keyword">null</span>;

- }

- 
- }

Service是一个抽象类,继承它必须实现其抽象方法 onBinde,其会返回一个IBinder对象,那么很显然,我们就需要在这个方法里返回我们的Binder了。

下面,我们先简单实现我们的Binder,如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_5">
    </embed>
  </div>
</div>
- <span class="keyword">public</span> <span class="keyword">class</span> DemoService <span class="keyword">extends</span> Service {

- 
- <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String TAG = <span class="string">&#8220;DemoService&#8221;</span>;

- 
- <span class="keyword">public</span> <span class="keyword">final</span> IDemoService.Stub mBinder = <span class="keyword">new</span> IDemoService.Stub() {

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> invoke() <span class="keyword">throws</span> RemoteException {

- Log.v(TAG, <span class="string">&#8220;Invoke -> Current Process From Server: &#8220;</span> + android.os.Process.myPid());

- }

- };

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> IBinder onBind(Intent intent) {

- Log.v(TAG, <span class="string">&#8220;Bind -> Current Process From Server: &#8220;</span> + android.os.Process.myPid());

- <span class="keyword">return</span> mBinder;

- }

- 
- <span class="keyword">public</span> <span class="keyword">boolean</span> onUnbind(Intent intent){

- Log.v(TAG, <span class="string">&#8220;Unbind -> Current Process From Server: &#8220;</span> + android.os.Process.myPid());

- <span class="keyword">return</span> <span class="keyword">super</span>.onUnbind(intent);

- }

- }

 

最后,在AndroidManifest.xml中注册Service,如下:

**[html]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_6">
    </embed>
  </div>
</div>
- <span class="tag"><</span><span class="tag-name">service</span>

- <span class="attribute">android:name</span>=<span class="attribute-value">&#8220;com.lms.service.DemoService&#8221;</span>

- <span class="attribute">android:exported</span>=<span class="attribute-value">&#8220;true&#8221;</span>

- <span class="attribute">android:process</span>=<span class="attribute-value">&#8220;:remote&#8221;</span> <span class="tag">></span>

- <span class="tag"><</span><span class="tag-name">intent-filter</span><span class="tag">></span>

- <span class="tag"><</span><span class="tag-name">category</span> <span class="attribute">android:name</span>=<span class="attribute-value">&#8220;android.intent.category.DEFAULT&#8221;</span> <span class="tag">/></span>

- 
- <span class="tag"><</span><span class="tag-name">action</span> <span class="attribute">android:name</span>=<span class="attribute-value">&#8220;com.lms.service.DemoService&#8221;</span> <span class="tag">/></span>

- <span class="tag"></</span><span class="tag-name">intent-filter</span><span class="tag">></span>

- <span class="tag"></</span><span class="tag-name">service</span><span class="tag">></span>

在这里,我们还需要定义一个intent-filter,以便Android系统在第三方调用的时候,可以通过隐式的intent来匹配到这个服务,同时还要注意两点:

1)android:process 必须设置值,至于什么值,好像关系并不大,表明可接受远程调用

2)android:exported设置为true,这表明此组件可供第三方调用,不过对于Service来说,这默认就是true的,所以我们不设也可以。但是对于Activity等来说,其值是默认为false的,这时候,如果我们想让我们的Activity为第三方调用,就要显式设置为true了。通常,在接入第三方插件的时候,我们会用到这个属性。

OK,到这里为止,我们已经简单地实现了我们的服务端服务了,接下来我们再继续实现我们客户端。

再创建一个项目,AidlDemoClient,然后将我们在服务端的这份aidl文件,包括包名等,复制到客户端代码中,编译一下,其会生成一份一样的java文件,不过此时,我们不再需要去实现Stub类了,我们只是需要去调用这个类就可以了,如下:

接着,我们只需要像平常一样调用我们的Service就可以了,所不同的是,由于这服务并不在我们进程内,所以我们必须用隐式的Intent去调用,由系统去匹配服务,从而调起,这也是为什么我们在服务端注册Service的时候,需要设置IntentFilter的原因了。

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_7">
    </embed>
  </div>
</div>
- <span class="keyword">public</span> <span class="keyword">class</span> MainActivity <span class="keyword">extends</span> ActionBarActivity {

- 
- <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String TAG = <span class="string">&#8220;DemoService&#8221;</span>;

- <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String ACTION_BIND_SERVICE = <span class="string">&#8220;com.lms.service.DemoService&#8221;</span>;

- 
- <span class="keyword">private</span> IDemoService mDemoService;

- 
- <span class="keyword">private</span> ServiceConnection mServiceConnection = <span class="keyword">new</span> ServiceConnection() {

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> onServiceDisconnected(ComponentName name) {

- mDemoService = <span class="keyword">null</span>;

- }

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> onServiceConnected(ComponentName name, IBinder service) {

- mDemoService = IDemoService.Stub.asInterface(service);

- <span class="keyword">try</span> {

- mDemoService.invoke();

- } <span class="keyword">catch</span> (RemoteException e) {

- <span class="comment">// TODO Auto-generated catch block</span>

- e.printStackTrace();

- }

- }

- };

- 
- <span class="annotation">@Override</span>

- <span class="keyword">protected</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) {

- <span class="keyword">super</span>.onCreate(savedInstanceState);

- setContentView(R.layout.activity_main);

- 
- Button btnHelloWorld = (Button) findViewById(R.id.btnBind);

- btnHelloWorld.setOnClickListener(<span class="keyword">new</span> OnClickListener() {

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> onClick(View v) {

- Intent intentService = <span class="keyword">new</span> Intent(ACTION_BIND_SERVICE);

- intentService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

- bindService(intentService, mServiceConnection, BIND_AUTO_CREATE);

- Log.v(TAG, <span class="string">&#8220;Current Process From Client: &#8220;</span> + android.os.Process.myPid());

- }

- });

- 
- Button btnUnbind = (Button) findViewById(R.id.btnUnbind);

- btnUnbind.setOnClickListener(<span class="keyword">new</span> OnClickListener() {

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> onClick(View v) {

- <span class="keyword">if</span>(mServiceConnection != <span class="keyword">null</span>){

- unbindService(mServiceConnection);

- mServiceConnection = <span class="keyword">null</span>;

- }

- }

- });

- 
- }

 

我们定义了两个按钮,当点击的时候,分别通过隐式的intent去启动服务并触发方法和解除绑定,我们可以看到在onServiceConnected中,我们利用了IDemoService.Stub.asInterface() 方法来实例化这个Binder,至于asterface是如何跨进程找到这个binder的,我们上一篇文章中已经简单地讲了一下。

接下来,我们可以启动这两个应用,来试一下啦。

从上面的画面中,我们可以看到,点击事件发生的线程ID是685,而真正接受服务和触发Invoke方法的是在进程676上面,于是我们就实现了跨进程通信了。

当然在这里,我们只是做了一个很简单的调用而已,而实际上我们还能够传递参数和接受返回值,而这些我们都可以在aidl文件中定义,不过要注意的是:

1)aidl中直接提供的数据类型只支持基本的数据类型和String

2)如果要支持我们自己的自定义的对象,我们的对象必须也通过aidl来定义,而且实现parceable接口,如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_8">
    </embed>
  </div>
</div>
- <span class="keyword">package</span> com.lms.aidl;

- 
- <span class="keyword">import</span> java.util.List;

- <span class="keyword">import</span> com.lms.aidl.Bean;

- 
- <span class="keyword">interface</span> ITestService {

- 
- List<Bean> getBean();

- 
- <span class="keyword">void</span> addBean(in Bean bean);

- }

而Bean的aidl文件如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_9" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_9">
    </embed>
  </div>
</div>
- <span class="keyword">package</span> com.lms.aidl;

- 
- parcelable Bean;

其具体实现如下:

**[java]** [view plain](http://blog.csdn.net/linmiansheng/article/details/42835229#)[copy](http://blog.csdn.net/linmiansheng/article/details/42835229#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/582805)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/582805/fork)
  <div>
    <embed id="ZeroClipboardMovie_10" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_10">
    </embed>
  </div>
</div>
- <span class="keyword">package</span> com.lms.aidl;

- 
- <span class="keyword">import</span> android.os.Parcel;

- <span class="keyword">import</span> android.os.Parcelable;

- 
- <span class="keyword">public</span> <span class="keyword">class</span> Bean <span class="keyword">implements</span> Parcelable {

- 
- <span class="keyword">private</span> <span class="keyword">int</span> i;

- <span class="keyword">private</span> String str;

- 
- <span class="keyword">public</span> Bean(){

- 
- }

- 
- <span class="comment">/**</span>

- <span class="comment">     * @return the i</span>

- <span class="comment">     */</span>

- <span class="keyword">public</span> <span class="keyword">int</span> getI() {

- <span class="keyword">return</span> i;

- }

- 
- <span class="comment">/**</span>

- <span class="comment">     * @param i the i to set</span>

- <span class="comment">     */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> setI(<span class="keyword">int</span> i) {

- <span class="keyword">this</span>.i = i;

- }

- 
- <span class="comment">/**</span>

- <span class="comment">     * @return the str</span>

- <span class="comment">     */</span>

- <span class="keyword">public</span> String getStr() {

- <span class="keyword">return</span> str;

- }

- 
- <span class="comment">/**</span>

- <span class="comment">     * @param str the str to set</span>

- <span class="comment">     */</span>

- <span class="keyword">public</span> <span class="keyword">void</span> setStr(String str) {

- <span class="keyword">this</span>.str = str;

- }

- 
- <span class="keyword">public</span> Bean(Parcel in) {

- readFromParcel(in);

- }

- 
- <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> Parcelable.Creator<Bean> CREATOR = <span class="keyword">new</span> Parcelable.Creator<Bean>() {

- 
- <span class="keyword">public</span> Bean createFromParcel(Parcel in) {

- <span class="keyword">return</span> <span class="keyword">new</span> Bean(in);

- }

- 
- <span class="keyword">public</span> Bean[] newArray(<span class="keyword">int</span> size) {

- <span class="keyword">return</span> <span class="keyword">new</span> Bean[size];

- }

- 
- };

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">int</span> describeContents() {

- <span class="keyword">return</span> <span class="number"></span>;

- }

- 
- <span class="annotation">@Override</span>

- <span class="keyword">public</span> <span class="keyword">void</span> writeToParcel(Parcel dest, <span class="keyword">int</span> flags) {

- dest.writeInt(i);

- dest.writeString(str);

- }

- 
- <span class="keyword">public</span> <span class="keyword">void</span> readFromParcel(Parcel in) {

- i = in.readInt();

- str = in.readString();

- }

- }

而我们可以从其通信的过程中拿到服务端的数据,如下:

好了,关于aidl的使用,我们就简单地介绍到这里吧,我会把两份Demo的代码都放上来,大家如果有兴趣,可以自己拿去参考一下。

简单版(只是调用方法):AidlDemo简单版

进阶版(进程间通信并且传递自定义对象):AidlDemo进阶版

转自:http://blog.csdn.net/linmiansheng/article/details/42835229

💬 评论