| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | page.title=Designing a Remote Interface Using AIDL |
| 2 | @jd:body |
| 3 | |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 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 | |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 23 | <p>Since each application runs in its own process, and you can write a service that |
| 24 | runs in a different process from your Application's UI, sometimes you need to pass objects |
| 25 | between processes. On the Android platform, one process can not normally access the memory |
| 26 | of another process. So to talk, they need to decompose their objects into primitives that |
| 27 | the 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 |
| 30 | for you.</p> |
| 31 | |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 32 | <p>AIDL (Android Interface Definition Language) is an <a |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 | href="http://en.wikipedia.org/wiki/Interface_description_language">IDL</a> |
| 34 | language used to generate code that enables two processes on an Android-powered device |
| 35 | to talk using interprocess communication (IPC). If you have code |
| 36 | in one process (for example, in an Activity) that needs to call methods on an |
| 37 | object in another process (for example, a Service), you would use AIDL to |
| 38 | generate 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> |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 42 | |
| 43 | |
| 44 | <h2 id="implementing">Implementing IPC Using AIDL</h2> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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> |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 65 | |
| 66 | <h3 id="aidlsyntax">Create an .aidl File</h3> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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. |
| 112 | package com.android.sample; |
| 113 | |
| 114 | // See the list above for which classes need |
| 115 | // import statements (hint--most of them) |
| 116 | import com.android.sample.IAtmService; |
| 117 | |
| 118 | // Declare the interface. |
| 119 | interface 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 | |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 137 | <h3 id="implementtheinterface">Implementing the Interface</h3> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 |
| 152 | files 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. |
| 156 | private 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> |
| Dirk Dougherty | fe1ffc3 | 2010-04-01 09:50:15 -0700 | [diff] [blame] | 164 | <li>By default, IPC calls are synchronous. If you know that an IPC service takes more than |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 |
| Dirk Dougherty | fe1ffc3 | 2010-04-01 09:50:15 -0700 | [diff] [blame] | 167 | is Not Responding" dialog). |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 172 | <h3 id="exposingtheinterface">Exposing Your Interface to Clients</h3> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 185 | |
| 186 | <h3 id="parcelable">Pass by value Parameters using Parcelables</h3> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 187 | |
| 188 | <p>If you have a class that you would like to send from one process to another through |
| 189 | an AIDL interface, you can do that. You must ensure that the code for your class is available |
| 190 | to the other side of the IPC. Generally, that means that you're talking to a service that you |
| 191 | started.</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 |
| 196 | current state of the object and writes it to a parcel.</li> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 197 | value 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 |
| 199 | the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li> |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 200 | <li>Last but not least, create an aidl file |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 201 | that declares your parcelable class (as shown below). If you are using a custom build process, |
| 202 | do not add the aidl file to your build. Similar to a header file in C, the aidl file isn't |
| 203 | compiled.</li> |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 204 | </ol> |
| 205 | |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 206 | <p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall |
| 207 | your objects.</p> |
| 208 | <p>Here is an example of how the {@link android.graphics.Rect} class implements the |
| 209 | Parcelable protocol.</p> |
| 210 | |
| 211 | <pre class="prettyprint"> |
| 212 | import android.os.Parcel; |
| 213 | import android.os.Parcelable; |
| 214 | |
| 215 | public 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"> |
| 257 | package android.graphics; |
| 258 | |
| 259 | // Declare Rect so AIDL can find it and knows that it implements |
| 260 | // the parcelable protocol. |
| 261 | parcelable Rect; |
| 262 | </pre> |
| 263 | |
| 264 | <p>The marshalling in the Rect class is pretty simple. Take a look at the other |
| 265 | methods on {@link android.os.Parcel} to see the other kinds of values you can write |
| 266 | to a Parcel.</p> |
| 267 | |
| 268 | <p class="warning"><b>Warning:</b> Don't forget the security implications of receiving data from |
| 269 | other processes. In this case, the rect will read four numbers from the parcel, |
| 270 | but it is up to you to ensure that these are within the acceptable range of |
| 271 | values for whatever the caller is trying to do. See |
| 272 | <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more |
| 273 | on how to keep your application secure from malware.</p> |
| 274 | |
| Scott Main | 0c11b99 | 2009-05-05 11:23:54 -0700 | [diff] [blame] | 275 | <h2 id="calling">Calling an IPC Method</h2> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 |
| Dianne Hackborn | 0766b2d | 2009-12-04 15:32:22 -0800 | [diff] [blame] | 300 | from the Remote Service sample in the ApiDemos project.</p> |
| 301 | <p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java |
| 302 | calling_a_service}</p> |
| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 303 | |
| 304 | |
| 305 | |