1page.title=Designing a Remote Interface Using AIDL 2@jd:body 3 4 5<div id="qv-wrapper"> 6<div id="qv"> 7<h2>In this document</h2> 8<ol> 9 <li><a href="#implementing">Implementing IPC Using AIDL</a> 10 <ol> 11 <li><a href="#aidlsyntax">Create an .aidl File</a></li> 12 <li><a href="#implementtheinterface">Implementing the Interface</a></li> 13 <li><a href="#exposingtheinterface">Exposing Your Interface to Clients</a></li> 14 <li><a href="#parcelable">Pass by value Parameters using Parcelables</a></li> 15 </ol> 16 </li> 17 <li><a href="#calling">Calling an IPC Method</a></li> 18</ol> 19</div> 20</div> 21 22 23<p>Since each application runs in its own process, and you can write a service that 24runs in a different process from your Application's UI, sometimes you need to pass objects 25between processes. On the Android platform, one process can not normally access the memory 26of another process. So to talk, they need to decompose their objects into primitives that 27the operating system can understand, and "marshall" the object across that boundary for you.</p> 28 29<p>The code to do that marshalling is tedious to write, so we provide the AIDL tool to do it 30for you.</p> 31 32<p>AIDL (Android Interface Definition Language) is an <a 33href="http://en.wikipedia.org/wiki/Interface_description_language">IDL</a> 34language used to generate code that enables two processes on an Android-powered device 35to talk using interprocess communication (IPC). If you have code 36in one process (for example, in an Activity) that needs to call methods on an 37object in another process (for example, a Service), you would use AIDL to 38generate code to marshall the parameters.</p> 39<p>The AIDL IPC mechanism 40 is interface-based, similar to COM or Corba, but lighter weight. It uses a proxy 41 class to pass values between the client and the implementation. </p> 42 43 44<h2 id="implementing">Implementing IPC Using AIDL</h2> 45<p>Follow these steps to implement an IPC service using AIDL.</p> 46<ol> 47 <li><strong><a href="#aidlsyntax">Create your .aidl file</a> </strong>- This 48 file defines an interface (<em>YourInterface</em>.aidl) that defines the 49 methods and fields available to a client. </li> 50 <li><strong>Add the .aidl file to your makefile</strong> - (the ADT Plugin for Eclipse 51 manages this for you). Android includes the compiler, called 52 AIDL, in the <code>tools/</code> directory. </li> 53 <li><strong><a href="#implementtheinterface">Implement your interface methods</a></strong> - 54 The AIDL compiler creates an interface in the Java programming language from your AIDL interface. 55 This interface has an inner abstract class named Stub that inherits the 56 interface (and implements a few additional methods necessary for the IPC 57 call). You must create a class that extends <em>YourInterface</em>.Stub 58 and implements the methods you declared in your .aidl file. </li> 59 <li><strong><a href="#exposingtheinterface">Expose your interface to clients</a></strong> - 60 If you're writing a service, you should extend {@link 61 android.app.Service Service} and override {@link android.app.Service#onBind 62 Service.onBind(Intent)} to return an instance of your class that implements your 63 interface. </li> 64</ol> 65 66<h3 id="aidlsyntax">Create an .aidl File</h3> 67<p>AIDL is a simple syntax that lets you declare an interface with one or more 68 methods, that can take parameters and return values. These parameters and return 69 values can be of any type, even other AIDL-generated interfaces. <em>However, it 70 is important to note</em> that you <em>must</em> import all non-built-in types, 71 <em>even if they are defined in the same package as your interface</em>. 72 Here are the data types that AIDL can support: </p> 73<ul> 74 <li>Primitive Java programming language types (int, boolean, etc) 75 — No <code>import</code> statement is needed. </li> 76 <li>One of the following classes (no <code>import</code> statements needed): 77 <ul> 78 <li><strong>String</strong></li> 79 <li><strong>List</strong> - All elements in the List must be one of the types 80 in this list, including other AIDL-generated interfaces and 81 parcelables. List may optionally be used as a "generic" class (e.g. 82 List<String>). 83 The actual concrete class that the other side will receive 84 will always be an ArrayList, although the method will be generated 85 to use the List interface. </li> 86 <li><strong>Map</strong> - All elements in the Map must be of one of the 87 types in this list, including other AIDL-generated interfaces and 88 parcelables. Generic maps, (e.g. of the form Map<String,Integer> 89 are not supported. 90 The actual concrete class that the other side will receive 91 will always be a HashMap, although the method will be generated 92 to use the Map interface.</li> 93 <li><strong>CharSequence</strong> - This is useful for the CharSequence 94 types used by {@link android.widget.TextView TextView} and other 95 widget objects. </li> 96 </ul> 97 </li> 98 <li>Other AIDL-generated interfaces, which are always passed by reference. 99 An <code>import</code> statement is always needed for these.</li> 100 <li>Custom classes that implement the <a href="#parcelable">Parcelable 101 protocol</a> and are passed by value. 102 An <code>import</code> statement is always needed for these.</li> 103</ul> 104<p>Here is the basic AIDL syntax:</p> 105<pre>// My AIDL file, named <em>SomeClass</em>.aidl 106// Note that standard comment syntax is respected. 107// Comments before the import or package statements are not bubbled up 108// to the generated interface, but comments above interface/method/field 109// declarations are added to the generated interface. 110 111// Include your fully-qualified package statement. 112package com.android.sample; 113 114// See the list above for which classes need 115// import statements (hint--most of them) 116import com.android.sample.IAtmService; 117 118// Declare the interface. 119interface IBankAccountService { 120 121 // Methods can take 0 or more parameters, and 122 // return a value or void. 123 int getAccountBalance(); 124 void setOwnerNames(in List<String> names); 125 126 // Methods can even take other AIDL-defined parameters. 127 BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService); 128 129 // All non-Java primitive parameters (e.g., int, bool, etc) require 130 // a directional tag indicating which way the data will go. Available 131 // values are in, out, inout. (Primitives are in by default, and cannot be otherwise). 132 // Limit the direction to what is truly needed, because marshalling parameters 133 // is expensive. 134 int getCustomerList(in String branch, out String[] customerList); 135}</pre> 136 137<h3 id="implementtheinterface">Implementing the Interface</h3> 138<p>AIDL generates an interface file for you with the same name as your .aidl 139 file. If you are using the Eclipse plugin, AIDL will automatically be run as part of 140 the build process (you don't need to run AIDL first and then build your project). 141 If you are not using the plugin, you should run AIDL first. </p> 142<p>The generated interface 143 includes an abstract inner class named Stub that declares all the methods 144 that you declared in your .aidl file. Stub also defines a few helper methods, 145 most notably asInterface(), which takes an IBinder (passed to a client's onServiceConnected() 146 implementation when applicationContext.bindService() succeeds), and returns an 147 instance of the interface used to call the IPC methods. See the section 148 <a href="#calling">Calling an IPC Method</a> for more details on how to make this cast.</p> 149<p>To implement your interface, extend <em>YourInterface</em>.Stub, 150 and implement the methods. (You can create the .aidl file and implement the stub 151 methods without building between--the Android build process will process .aidl 152files before .java files.) </p> 153<p>Here is an example of implementing an interface called IRemoteService, which exposes 154 a single method, getPid(), using an anonymous instance:</p> 155<pre>// No need to import IRemoteService if it's in the same project. 156private final IRemoteService.Stub mBinder = new IRemoteService.Stub(){ 157 public int getPid(){ 158 return Process.myPid(); 159 } 160}</pre> 161<p>A few rules about implementing your interface: </p> 162<ul> 163 <li>No exceptions that you throw will be sent back to the caller.</li> 164 <li>IPC calls are synchronous. If you know that an IPC service takes more than 165 a few milliseconds to complete, you should not call it in the Activity/View thread, 166 because it might hang the application (Android might display an "Application 167 is Not Responding" dialog). 168 Try to call them in a separate thread. </li> 169 <li>Only methods are supported; you cannot declare static fields in an AIDL interface.</li> 170</ul> 171 172<h3 id="exposingtheinterface">Exposing Your Interface to Clients</h3> 173<p>Now that you've got your interface implementation, you need to expose it to clients. 174 This is known as "publishing your service." To publish a service, 175 inherit {@link android.app.Service Service} and implement {@link android.app.Service#onBind 176 Service.onBind(Intent)} to return an instance of the class that implements your interface. 177 Here's a code snippet of a service that exposes the IRemoteService 178 interface to clients. </p> 179<pre>public class RemoteService extends Service { 180... 181{@include development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java 182 exposing_a_service} 183}</pre> 184 185 186<h3 id="parcelable">Pass by value Parameters using Parcelables</h3> 187 188<p>If you have a class that you would like to send from one process to another through 189an AIDL interface, you can do that. You must ensure that the code for your class is available 190to the other side of the IPC. Generally, that means that you're talking to a service that you 191started.</p> 192<p>There are five parts to making a class support the Parcelable protocol:</b> 193<ol> 194<li>Make your class implement the {@link android.os.Parcelable} interface.</li> 195<li>Implement the method <code>public void writeToParcel(Parcel out)</code> that takes the 196current state of the object and writes it to a parcel.</li> 197value in a parcel into your object.</li> 198<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing 199the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li> 200<li>Last but not least, create an aidl file 201that declares your parcelable class (as shown below). If you are using a custom build process, 202do not add the aidl file to your build. Similar to a header file in C, the aidl file isn't 203compiled.</li> 204</ol> 205 206<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall 207your objects.</p> 208<p>Here is an example of how the {@link android.graphics.Rect} class implements the 209Parcelable protocol.</p> 210 211<pre class="prettyprint"> 212import android.os.Parcel; 213import android.os.Parcelable; 214 215public final class Rect implements Parcelable { 216 public int left; 217 public int top; 218 public int right; 219 public int bottom; 220 221 public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() { 222 public Rect createFromParcel(Parcel in) { 223 return new Rect(in); 224 } 225 226 public Rect[] newArray(int size) { 227 return new Rect[size]; 228 } 229 }; 230 231 public Rect() { 232 } 233 234 private Rect(Parcel in) { 235 readFromParcel(in); 236 } 237 238 public void writeToParcel(Parcel out) { 239 out.writeInt(left); 240 out.writeInt(top); 241 out.writeInt(right); 242 out.writeInt(bottom); 243 } 244 245 public void readFromParcel(Parcel in) { 246 left = in.readInt(); 247 top = in.readInt(); 248 right = in.readInt(); 249 bottom = in.readInt(); 250 } 251} 252</pre> 253 254<p>Here is Rect.aidl for this example</p> 255 256<pre class="prettyprint"> 257package android.graphics; 258 259// Declare Rect so AIDL can find it and knows that it implements 260// the parcelable protocol. 261parcelable Rect; 262</pre> 263 264<p>The marshalling in the Rect class is pretty simple. Take a look at the other 265methods on {@link android.os.Parcel} to see the other kinds of values you can write 266to a Parcel.</p> 267 268<p class="warning"><b>Warning:</b> Don't forget the security implications of receiving data from 269other processes. In this case, the rect will read four numbers from the parcel, 270but it is up to you to ensure that these are within the acceptable range of 271values for whatever the caller is trying to do. See 272<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more 273on how to keep your application secure from malware.</p> 274 275<h2 id="calling">Calling an IPC Method</h2> 276<p>Here are the steps a calling class should make to call your remote interface: </p> 277<ol> 278 <li>Declare a variable of the interface type that your .aidl file defined. </li> 279 <li>Implement {@link android.content.ServiceConnection ServiceConnection}. </li> 280 <li>Call {@link android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int) 281 Context.bindService()}, passing in your ServiceConnection implementation. </li> 282 <li>In your implementation of {@link android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,android.os.IBinder) 283 ServiceConnection.onServiceConnected()}, you will receive an {@link android.os.IBinder 284 IBinder} instance (called <em>service</em>). Call <code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to 285 cast the returned parameter to <em>YourInterface</em> type.</li> 286 <li>Call the methods that you defined on your interface. You should always trap 287 {@link android.os.DeadObjectException} exceptions, which are thrown when 288 the connection has broken; this will be the only exception thrown by remote 289 methods.</li> 290 <li>To disconnect, call {@link android.content.Context#unbindService(android.content.ServiceConnection) 291 Context.unbindService()} with the instance of your interface. </li> 292</ol> 293<p>A few comments on calling an IPC service:</p> 294<ul> 295 <li>Objects are reference counted across processes. </li> 296 <li>You can send anonymous objects 297 as method arguments. </li> 298</ul> 299<p>Here is some sample code demonstrating calling an AIDL-created service, taken 300 from the Remote Activity sample in the ApiDemos project.</p> 301<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteServiceBinding.java 302 exposing_a_service}</p> 303 304 305 306