首页 > 代码库 > Android服务之AIDL

Android服务之AIDL

在android开发过程中,为了让其他的应用程序,也可以访问本应用程序的服务,android系统采用远程过程调用来实现。android通过接口来公开定义的服务。我们将能够夸进程访问的服务成为AIDL服务(Android Interface Definition Language)。本节主要讲述通过aidl服务来传递数据。aidl支持的数据类型“简单数据类型、String和char、List和Map、aidl自动生成的接口、实现android.Parcelable的类。

1.建立aidl服务

在Eclipse中建立android_adil应用程序,在java的包目录中建立一个IMyService.aidl文件.

1 package com.example.android_demo_aidl;2 import com.example.android_demo_aidl.Person;3 interface IMyService4 {5     Map getMap(in String key,in Person person);6     Person getPerson();7 }
IMyService.aidl

Person是实现了parcelable接口的类,需要使用import导入。in表示该值可以在客户端设置,out表示该值可以在服务端设置,inout表示该值既可以在客户端设置,也可以再服务端设置。如果aidl正确,会自动生成IMyService.java文件。

在包中建立Person类。

 1 package com.example.android_demo_aidl; 2  3 import android.os.Parcel; 4 import android.os.Parcelable; 5  6 public class Person implements Parcelable { 7  8     private int id; 9     private String name;10     private int age;11     public static final  Parcelable.Creator<Person> CREATOR= new Parcelable.Creator<Person>() {12         13         @Override14         public Person[] newArray(int size) {15             // TODO Auto-generated method stub16             return new Person[size];17         }18         19         @Override20         public Person createFromParcel(Parcel source) {21             // TODO Auto-generated method stub22             return new Person(source);23         }24     };25     public Person()26     {27     }28     private Person(Parcel in)29     {30         readFormParce(in);31     }32     private void readFormParce(Parcel in) {33         // TODO Auto-generated method stub34         id=in.readInt();35         name=in.readString();36         age=in.readInt();37                 38     }39     public int describeContents()40     {41         return 0;42     }43     public void writeToParcel(Parcel dest,int flags)44     {45         dest.writeInt(id);46         dest.writeString(name);47         dest.writeInt(age);48     }49     public int getId()50     {51         return id;52     }53     public void setId(int id)54     {55         this.id=id;56     }57     public String getName()58     {59         return name;60     }61     public void setName(String name)62     {63         this.name=name;64     }65     public int getAge()66     {67         return age;68     }69     public void setAge(int age)70     {71         this.age=age;72     }73 }
Person

Person类定义name,age等成员变量,实现了接口parcelable。同时必须定义CREATOR的常量,类型为Parcelable.Creator。在writeToParcel中将序列化的值传入Parcel。

建立Person.aidl

parcelable Person;

编写MyService类

 1 package com.example.android_demo_aidl; 2  3 import java.util.HashMap; 4 import java.util.Map; 5  6 import android.app.Service; 7 import android.content.Intent; 8 import android.os.IBinder; 9 import android.os.RemoteException;10 import android.util.Log;11 12 public class MyService extends Service {13 14     public class MyServiceImpl extends IMyService.Stub15     {16 17         @Override18         public Map getMap(String key, Person person) throws RemoteException {19             // TODO Auto-generated method stub20             Map map = new HashMap<String,String>();21             map.put("id", person.getId());22             map.put("age", person.getAge());23             map.put("name", person.getName());24             map.put("person", person);25             return map;26         }27 28         @Override29         public Person getPerson() throws RemoteException {30             // TODO Auto-generated method stub31             Person person = new Person();32             person.setAge(18);33             person.setId(1);34             person.setName("Tom");35             return person;36         }37 38         39     40     }41     @Override42     public IBinder onBind(Intent intent) {43         // TODO Auto-generated method stub44         return new MyServiceImpl();45     }46     @Override47     public void onCreate() {48         // TODO Auto-generated method stub49         super.onCreate();50         Log.d("test", "oncreate");51     }52 }
MyService

在MyService类中定义一个新类MyServiceIm继承于IMyService.Stub.需要实现在接口中定义的方法。MyService类继承android.Service,在绑定方法中,返回一个实例。

最后,在AndroidManifest.xml中配置该服务。

1         <service android:name=".MyService">2             <intent-filter >3                 <action android:name="com.example.android_demo_aidl.IMyService"/>4             </intent-filter>5         </service>
AndroidManifest.xml

android:name,在客户端通过该id调用服务。

2.调用服务

在Eclipse中建立新的android应用程序,android_ail_client。在调用服务之前,需要绑定服务,通过bindService进行服务的绑定。将服务端自动生成的IMyservice.java连同包一起复制到新的应用程序用。程序结构如下图

  1 package com.example.android_demo_aidl_client;  2   3 import com.example.android_demo_aidl.IMyService;  4   5 import android.support.v7.app.ActionBarActivity;  6 import android.content.ComponentName;  7 import android.content.Context;  8 import android.content.Intent;  9 import android.content.ServiceConnection; 10 import android.os.Bundle; 11 import android.os.IBinder; 12 import android.util.Log; 13 import android.view.Menu; 14 import android.view.MenuItem; 15 import android.view.View; 16 import android.view.View.OnClickListener; 17 import android.widget.Button; 18 import android.widget.TextView; 19  20 public class MainActivity extends ActionBarActivity implements OnClickListener { 21  22     private Button btnstart; 23     private Button btninvoke; 24     private IMyService myService=null; 25     private TextView textView; 26     private ServiceConnection conn=new ServiceConnection() { 27          28         @Override 29         public void onServiceDisconnected(ComponentName name) { 30             // TODO Auto-generated method stub 31             Log.d("test", "绑定错误"); 32         } 33          34         @Override 35         public void onServiceConnected(ComponentName name, IBinder service) { 36             // TODO Auto-generated method stub 37             myService=IMyService.Stub.asInterface(service); 38             btninvoke.setEnabled(true); 39         } 40     }; 41     @Override 42     protected void onCreate(Bundle savedInstanceState) { 43         super.onCreate(savedInstanceState); 44         setContentView(R.layout.activity_main); 45         btnstart=(Button)findViewById(R.id.button1); 46         btninvoke=(Button)findViewById(R.id.button2); 47         textView=(TextView)findViewById(R.id.textView1); 48      49         btninvoke.setOnClickListener(this); 50         btnstart.setOnClickListener(this); 51     } 52  53     @Override 54     public boolean onCreateOptionsMenu(Menu menu) { 55         // Inflate the menu; this adds items to the action bar if it is present. 56         getMenuInflater().inflate(R.menu.main, menu); 57         return true; 58     } 59  60     @Override 61     public boolean onOptionsItemSelected(MenuItem item) { 62         // Handle action bar item clicks here. The action bar will 63         // automatically handle clicks on the Home/Up button, so long 64         // as you specify a parent activity in AndroidManifest.xml. 65         int id = item.getItemId(); 66         if (id == R.id.action_settings) { 67             return true; 68         } 69         return super.onOptionsItemSelected(item); 70     } 71  72     @Override 73     public void onClick(View v) { 74         // TODO Auto-generated method stub 75         switch(v.getId()) 76         { 77         case R.id.button1: 78             bindService(new Intent("com.example.android_demo_aidl.IMyService"), conn, Context.BIND_AUTO_CREATE); 79             break; 80         case R.id.button2: 81             try 82             { 83                 String s=""; 84             s="person.id="+myService.getPerson().getId()+"\n"; 85             s+="person.name="+myService.getPerson().getName()+"\n"; 86             s+="person.age="+myService.getPerson().getAge(); 87                 textView.setText(s); 88             } 89             catch(Exception e) 90             { 91                 Log.d("test",e.getMessage()); 92             } 93             break; 94         } 95     } 96     @Override 97     protected void onDestroy() { 98         // TODO Auto-generated method stub 99         super.onDestroy();100          unbindService(conn);101     }102 }
MainActivity

在该段代码中,通过ServiceConnection获取Aidl服务的对象实例。在调用服务之前需先绑定服务。

3.程序运行截图

运行的时候,需要先运行服务端程序,再运行客户端程序。

 

Android服务之AIDL