Android支持两种类型的服务:本地服务与远程服务。本地服务只能供承载它的应用程序使用,而远程服务还可以供其它应用程序使用。在Android中,远程服务可以使用AIDL(Android Interface Definition Language)向客户端定义自身。
下面说明创建AIDL服务的步骤:
- 编写一个AIDL文件(以.aidl为后缀)来向客户端定义接口,AIDL文件使用java语法。
- 将此AIDL文件添加到eclipse项目的src目录下。ADT将会调用AIDL编译器自动生成一个java接口,此文件位于gen目录下,可以打开查看。
- 实现一个服务并从onBind()方法中返回生成的接口(一般我们在服务中实现这个接口,然后在onBind()方法中返回其实例)。
- 在Manifest中配置Service,这里我们必须要使用intent-filter,并为其添加action属性。
废话不说,上代码(很简单的代码):
项目结构
Person.aidl(注意:接口不能有修饰符)
- package kevin.demo;
- interface Person {
- int getAge(String name);
- }<strong>
- </strong>
RemoteServcie
- package kevin.demo;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- public class RemoteService extends Service {
- public static final String REMOTE_SERVICE_ACTION = "kevin.demo.action.remote";
- @Override
- public void onCreate() {
- // TODO Auto-generated method stub
- super.onCreate();
- System.out.println("service created..");
- }
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- System.out.println("Service bound..");
- // 返回远程服务的实例
- return new PersonIml();
- }
- @Override
- public boolean onUnbind(Intent intent) {
- // TODO Auto-generated method stub
- System.out.println("service unbound");
- return super.onUnbind(intent);
- }
- @Override
- public void onStart(Intent intent, int startId) {
- // TODO Auto-generated method stub
- super.onStart(intent, startId);
- System.out.println("Service started..");
- }
- // 远程服务的实现
- private class PersonIml extends Person.Stub {
- @Override
- public int getAge(String name) throws RemoteException {
- if (name.equals("kevin")) {
- return 22;
- }
- return -1;
- }
- }
- }<strong>
- </strong>
Android Manifest
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="kevin.demo" android:versionCode="1" android:versionName="1.0">
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <service android:name="RemoteService">
- <intent-filter>
- <action android:name="kevin.demo.action.remote"></action>
- </intent-filter>
- </service>
- </application>
- </manifest>
接下来我们实现客户端的项目,通过此项目我们可以访问刚才定义的远程服务。这里我们必须把在远程服务项目中定义 的AIDL接口复制到此项目中,并且要保证包名与远程项目中此接口文件所在包名相同,并且此包中的Activity不能和此文件同包。下面是项目结构与代码:
Person.aidl同上
RemoteClient.java
- package kevin.client;
- import kevin.demo.Person;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.widget.Toast;
- public class RemoteClient extends Activity {
- /** Called when the activity is first created. */
- private static final String TAG = "RemoteClient";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- @Override
- protected void onStart() {
- // TODO Auto-generated method stub
- super.onStart();
- System.out.println(TAG + " onStart..");
- bindService(new Intent("kevin.demo.action.remote"), conn,
- BIND_AUTO_CREATE);
- System.out.println(TAG + "bindService invoked..");
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- super.onStop();
- unbindService(conn);
- }
- private ServiceConnection conn = new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // TODO Auto-generated method stub
- System.out.println("RemoteClient service disconnected..");
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- // TODO Auto-generated method stub
- System.out.println("RemoteClient servcie connected..");
- System.out.println("-------------------");
- Person remoteServ = Person.Stub.asInterface(service);
- try {
- System.out.println("My age is: " + remoteServ.getAge("kevin"));
- Toast.makeText(RemoteClient.this,
- "My age is: " + remoteServ.getAge("kevin"),
- Toast.LENGTH_LONG).show();
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("-------------------");
- }
- };
- }