http://www.android123.com.cn/androidkaifa/597.html by:
Android的服务开发中我们可能都是Activity和Service同进程处理,但想象过系统提供的各种ServiceManager吗? 比如 SensorManager、SmsManager 这些服务可以提供给任意应用,对于这样的公共后台服务器开发类似我们在Win32的COM组件或Symbian的C/S框架,我们需要AIDL(Android Interface Definition Language即Android接口定义语言)来支持服务IPC(interprocess communication IPC)和各个进程的组件进行通讯。
我们将分5节完成以下几个问题
1. AIDL的概念 (本节)
2. Service绑定
3. AIDL基础框架
4. Parcelable
5. Android开源项目中的AIDL示例分析
使用Win32+Eclipse+ADT开发的网友可以通过在SDK的platform/android-x.y/tools文件夹中找到 aidl.exe 文件,这里android123提醒大家注意的是并不是sdk根目录下的tools文件一定要进入到platform中去,其中android-x.y是相应的sdk版本。我们首先执行无参数的aidl可以看到完整的帮助如图:
当然从目前的新版ADT插件来说可以自动的通过AIDL文件生成Java代码,如果使用Ants方式编译可以考虑上面的cmd命令行方式
上次我们在 Android AIDL全攻略一 中讲到了AIDL的概念,由于AIDL属于服务相关内容,同时需要涉及到Service绑定问题,作为整个Android AIDL系列教程的第二节我们一起来看下Service绑定问题。我们过去使用一些轻量级的服务可能直接startService启动,通过Service中的onStart方法可以获取执行服务的命令行,其中参数Intent可以传递内容,当然作为低频度的传输也可以考虑Broadcast来交互Activity和Service,但是作为正常专业的长久的服务Android123还是推荐大家使用绑定机制来实现数据的传输。其中系统级别的跨进程服务AIDL就是基于Service绑定方式的。
作为Service必须重写一个方法就是onBind(),如果使用startService方式启动服务,则我们在onBind()中返回一个null的IBinder对象。今天使用bindService方法将如何写呢? 具体的步骤如下:
1. 使用bindService方法启动服务,bindService (Intent service, ServiceConnection conn, int flags) 有三个参数,这里大家可能会对第二个ServiceConnection和最后第三个参数的标识感到陌生,一般在我们调用bindService时需要一个ServiceConnection获取服务实例以及状态,代码如下
private ServiceConnection sc = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Toast.makeText(ctx, "android123 service connected", Toast.LENGTH_LONG).show(); } @Override public void onServiceDisconnected(ComponentName name) { Toast.makeText(ctx, "android123 service disconnected", Toast.LENGTH_LONG).show(); } };这样,我们在服务的连接和断开时都会收到一个Toast的消息提示,而bindService最后的参数一般使用BIND_AUTO_CREATE 标识自动创建。所以一般我们绑定一个服务,使用下面的代码
bindService(intent, sc, Service.BIND_AUTO_CREATE);
来启动服务,而解除绑定可以用 unbindService(sc);
2. 上面说的都是在非具体的Service中进行操作,下面来看看Service需要处理哪些内容:
public boolean onUnbind (Intent intent) //反绑定服务时做清理工作
public void onRebind (Intent intent) //重新绑定时触发
public abstract IBinder onBind (Intent intent) //我们需要返回一个IBinder对象,所以要实现这个抽象方法
3. 实现onBind方法,这里我们简单的给服务的调用者传递一个Service的实例
public class cwjBinder extends Binder{
cwjService fetchService() { return cwjService.this; }
}
我们在构造Service时实例化cwjBinder使用
cwjBinder binderObj=new cwjBinder();
这时我们在onBind()的返回时设置为binderObj而不是null了。
4. 回到我们调用Service的地方,在ServiceConnection中的 onServiceConnected 方法第二个参数就是我们刚才的IBinder实例了, 该方法原型为 public void onServiceConnected(ComponentName name, IBinder service) ,这时我们可以调用 fetchService方法了。有关Android AIDL的另一注意点Android开发网将在明天讲解。
在Android AIDL全攻略的一和二中我们提到了相关的基础内容,本次我们将通过实例代码完成AIDL框架。这里Android123推荐大家使用Eclipse+ADT的开发方式以提高我们的效率,有关ants和aidl命令的编译方式不了解的可以来函至android123@163.com 我们会及时回复。
1. AIDL的语法和框架,Android IDL语言类似Java的接口,可以使用常规的String、Boolean等类型,但对于数值传递我们需要使用 Parcelable 接口,如果你不了解 Parcelable 的使用,Android123将在下节详细解释。
2. 在我们的工程中创建一个 xxx的.aidl文件,这时回到Eclipse重新构建工程可以发现在/res/gen的文件夹下会自动生成Ixxx.java文件,ADT帮我们实现这个接口的stub类,具体的AIDL文件内容比如为:
package com.android123.cwj;
interface IWeatherService { int getTemperature(in String city,out String temperature);
int getTemperatureList(in String city, out String[] temperature);}
上面我们注意AIDL文件中的方法,参数类型前面有in和out关键字,类似Win32 COM中的IN或OUT,分别代表传入和输出,对于Java文件,ADT插件会在res/gen中生成一个java文件实现Stub子类。本文未完成,