| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 1 | page.title=Android Interface Definition Language (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="#Defining">Defining an AIDL Interface</a> |
| 10 | <ol> |
| 11 | <li><a href="#Create">Create the .aidl file</a></li> |
| 12 | <li><a href="#Implement">Implement the interface</a></li> |
| 13 | <li><a href="#Expose">Expose the interface to clients</a></li> |
| 14 | </ol> |
| 15 | </li> |
| 16 | <li><a href="#PassingObjects">Passing Objects over IPC</a></li> |
| 17 | <li><a href="#Calling">Calling an IPC Method</a></li> |
| 18 | </ol> |
| 19 | |
| 20 | <h2>See also</h2> |
| 21 | <ol> |
| 22 | <li><a href="{@docRoot}guide/components/bound-services.html">Bound Services</a></li> |
| 23 | </ol> |
| 24 | |
| 25 | </div> |
| 26 | </div> |
| 27 | |
| 28 | |
| 29 | <p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have |
| 30 | worked with. It allows you to define the programming interface that both |
| 31 | the client and service agree upon in order to communicate with each other using |
| 32 | interprocess communication (IPC). On Android, one process cannot normally access the |
| 33 | memory of another process. So to talk, they need to decompose their objects into primitives that the |
| 34 | operating system can understand, and marshall the objects across that boundary for you. The code to |
| 35 | do that marshalling is tedious to write, so Android handles it for you with AIDL.</p> |
| 36 | |
| 37 | <p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from |
| 38 | different applications to access your service for IPC and want to handle multithreading in your |
| 39 | service. If you do not need to perform concurrent IPC across |
| 40 | different applications, you should create your interface by <a |
| 41 | href="{@docRoot}guide/components/bound-services.html#Binder">implementing a |
| 42 | Binder</a> or, if you want to perform IPC, but do <em>not</em> need to handle multithreading, |
| 43 | implement your interface <a |
| 44 | href="{@docRoot}guide/components/bound-services.html#Messenger">using a Messenger</a>. |
| 45 | Regardless, be sure that you understand <a |
| 46 | href="{@docRoot}guide/components/bound-services.html">Bound Services</a> before |
| 47 | implementing an AIDL.</p> |
| 48 | |
| 49 | <p>Before you begin designing your AIDL interface, be aware that calls to an AIDL interface are |
| 50 | direct function calls. You should not make assumptions about the thread in which the call |
| 51 | occurs. What happens is different depending on whether the call is from a thread in the |
| 52 | local process or a remote process. Specifically:</p> |
| 53 | |
| 54 | <ul> |
| 55 | <li>Calls made from the local process are executed in the same thread that is making the call. If |
| 56 | this is your main UI thread, that thread continues to execute in the AIDL interface. If it is |
| 57 | another thread, that is the one that executes your code in the service. Thus, if only local |
| 58 | threads are accessing the service, you can completely control which threads are executing in it (but |
| 59 | if that is the case, then you shouldn't be using AIDL at all, but should instead create the |
| 60 | interface by <a href="{@docRoot}guide/components/bound-services.html#Binder">implementing a |
| 61 | Binder</a>).</li> |
| 62 | |
| 63 | <li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of |
| 64 | your own process. You must be prepared for incoming calls from unknown threads, with multiple calls |
| 65 | happening at the same time. In other words, an implementation of an AIDL interface must be |
| 66 | completely thread-safe.</li> |
| 67 | |
| 68 | <li>The {@code oneway} keyword modifies the behavior of remote calls. When used, a remote call does |
| 69 | not block; it simply sends the transaction data and immediately returns. |
| 70 | The implementation of the interface eventually receives this as a regular call from the {@link |
| 71 | android.os.Binder} thread pool as a normal remote call. If {@code oneway} is used with a local call, |
| 72 | there is no impact and the call is still synchronous.</li> |
| 73 | </ul> |
| 74 | |
| 75 | |
| 76 | <h2 id="Defining">Defining an AIDL Interface</h2> |
| 77 | |
| 78 | <p>You must define your AIDL interface in an {@code .aidl} file using the Java |
| 79 | programming language syntax, then save it in the source code (in the {@code src/} directory) of both |
| 80 | the application hosting the service and any other application that binds to the service.</p> |
| 81 | |
| 82 | <p>When you build each application that contains the {@code .aidl} file, the Android SDK tools |
| 83 | generate an {@link android.os.IBinder} interface based on the {@code .aidl} file and save it in |
| 84 | the project's {@code gen/} directory. The service must implement the {@link android.os.IBinder} |
| 85 | interface as appropriate. The client applications can then bind to the service and call methods from |
| 86 | the {@link android.os.IBinder} to perform IPC.</p> |
| 87 | |
| 88 | <p>To create a bounded service using AIDL, follow these steps:</p> |
| 89 | <ol> |
| 90 | <li><a href="#CreateAidl">Create the .aidl file</a> |
| 91 | <p>This file defines the programming interface with method signatures.</p> |
| 92 | </li> |
| 93 | <li><a href="#ImplementTheInterface">Implement the interface</a> |
| 94 | <p>The Android SDK tools generate an interface in the Java programming language, based on your |
| 95 | {@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends |
| 96 | {@link android.os.Binder} and implements methods from your AIDL interface. You must extend the |
| 97 | {@code Stub} class and implement the methods.</p> |
| 98 | </li> |
| 99 | <li><a href="#ExposeTheInterface">Expose the interface to clients</a> |
| 100 | <p>Implement a {@link android.app.Service Service} and override {@link |
| 101 | android.app.Service#onBind onBind()} to return your implementation of the {@code Stub} |
| 102 | class.</p> |
| 103 | </li> |
| 104 | </ol> |
| 105 | |
| 106 | <p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after |
| 107 | your first release must remain backward compatible in order to avoid breaking other applications |
| 108 | that use your service. That is, because your {@code .aidl} file must be copied to other applications |
| 109 | in order for them to access your service's interface, you must maintain support for the original |
| 110 | interface.</p> |
| 111 | |
| 112 | |
| 113 | <h3 id="Create">1. Create the .aidl file</h3> |
| 114 | |
| 115 | <p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can |
| 116 | take parameters and return values. The parameters and return values can be of any type, even other |
| 117 | AIDL-generated interfaces.</p> |
| 118 | |
| 119 | <p>You must construct the {@code .aidl} file using the Java programming language. Each {@code .aidl} |
| 120 | file must define a single interface and requires only the interface declaration and method |
| 121 | signatures.</p> |
| 122 | |
| 123 | <p>By default, AIDL supports the following data types:</p> |
| 124 | |
| 125 | <ul> |
| 126 | <li>All primitive types in the Java programming language (such as {@code int}, {@code long}, |
| 127 | {@code char}, {@code boolean}, and so on)</li> |
| 128 | <li>{@link java.lang.String}</li> |
| 129 | <li>{@link java.lang.CharSequence}</li> |
| 130 | <li>{@link java.util.List} |
| 131 | <p>All elements in the {@link java.util.List} must be one of the supported data types in this |
| 132 | list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link |
| 133 | java.util.List} may optionally be used as a "generic" class (for example, |
| 134 | <code>List<String></code>). |
| 135 | The actual concrete class that the other side receives is always an {@link |
| 136 | java.util.ArrayList}, although the method is generated to use the {@link |
| 137 | java.util.List} interface.</p> |
| 138 | </li> |
| 139 | <li>{@link java.util.Map} |
| 140 | <p>All elements in the {@link java.util.Map} must be one of the supported data types in this |
| 141 | list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps, |
| 142 | (such as those of the form |
| 143 | {@code Map<String,Integer>} are not supported. The actual concrete class that the other side |
| 144 | receives is always a {@link java.util.HashMap}, although the method is generated to |
| 145 | use the {@link java.util.Map} interface.</p> |
| 146 | </li> |
| 147 | </ul> |
| 148 | |
| 149 | <p>You must include an {@code import} statement for each additional type not listed above, even if |
| 150 | they are defined in the same package as your interface.</p> |
| 151 | |
| 152 | <p>When defining your service interface, be aware that:</p> |
| 153 | <ul> |
| 154 | <li>Methods can take zero or more parameters, and return a value or void.</li> |
| 155 | <li>All non-primitive parameters require a directional tag indicating which way the data goes. |
| 156 | Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below). |
| 157 | <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p> |
| 158 | <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly |
| 159 | needed, because marshalling parameters is expensive.</p></li> |
| 160 | <li>All code comments included in the {@code .aidl} file are included in the generated {@link |
| 161 | android.os.IBinder} interface (except for comments before the import and package |
| 162 | statements).</li> |
| 163 | <li>Only methods are supported; you cannot expose static fields in AIDL.</li> |
| 164 | </ul> |
| 165 | |
| 166 | <p>Here is an example {@code .aidl} file:</p> |
| 167 | |
| 168 | <pre> |
| 169 | // IRemoteService.aidl |
| 170 | package com.example.android; |
| 171 | |
| 172 | // Declare any non-default types here with import statements |
| 173 | |
| 174 | /** Example service interface */ |
| 175 | interface IRemoteService { |
| 176 | /** Request the process ID of this service, to do evil things with it. */ |
| 177 | int getPid(); |
| 178 | |
| 179 | /** Demonstrates some basic types that you can use as parameters |
| 180 | * and return values in AIDL. |
| 181 | */ |
| 182 | void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, |
| 183 | double aDouble, String aString); |
| 184 | } |
| 185 | </pre> |
| 186 | |
| 187 | <p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you |
| 188 | build your application, the SDK tools generate the {@link android.os.IBinder} interface file in your |
| 189 | project's {@code gen/} directory. The generated file name matches the {@code .aidl} file name, but |
| 190 | with a {@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code |
| 191 | IRemoteService.java}).</p> |
| 192 | |
| 193 | <p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you |
| 194 | do not use Eclipse, then the Ant tool generates the binder class next time you build your |
| 195 | application—you should build your project with <code>ant debug</code> (or <code>ant |
| 196 | release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can |
| 197 | link against the generated class.</p> |
| 198 | |
| 199 | |
| 200 | <h3 id="Implement">2. Implement the interface</h3> |
| 201 | |
| 202 | <p>When you build your application, the Android SDK tools generate a {@code .java} interface file |
| 203 | named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub} |
| 204 | that is an abstract implementation of its parent interface (for example, {@code |
| 205 | YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p> |
| 206 | |
| 207 | <p class="note"><strong>Note:</strong> {@code Stub} also |
| 208 | defines a few helper methods, most notably {@code asInterface()}, which takes an {@link |
| 209 | android.os.IBinder} (usually the one passed to a client's {@link |
| 210 | android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and |
| Scott Main | f8daf19 | 2013-01-04 17:41:54 -0800 | [diff] [blame] | 211 | returns an instance of the stub interface. See the section <a href="#Calling">Calling an IPC |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 212 | Method</a> for more details on how to make this cast.</p> |
| 213 | |
| 214 | <p>To implement the interface generated from the {@code .aidl}, extend the generated {@link |
| 215 | android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods |
| 216 | inherited from the {@code .aidl} file.</p> |
| 217 | |
| 218 | <p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the |
| 219 | {@code IRemoteService.aidl} example, above) using an anonymous instance:</p> |
| 220 | |
| 221 | <pre> |
| 222 | private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { |
| 223 | public int getPid(){ |
| 224 | return Process.myPid(); |
| 225 | } |
| 226 | public void basicTypes(int anInt, long aLong, boolean aBoolean, |
| 227 | float aFloat, double aDouble, String aString) { |
| 228 | // Does nothing |
| 229 | } |
| 230 | }; |
| 231 | </pre> |
| 232 | |
| 233 | <p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}), |
| 234 | which defines the RPC interface for the service. In the next step, this instance is exposed to |
| 235 | clients so they can interact with the service.</p> |
| 236 | |
| 237 | <p>There are a few rules you should be aware of when implementing your AIDL interface: </p> |
| 238 | <ul> |
| 239 | <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think |
| 240 | about multithreading from the start and properly build your service to be thread-safe.</li> |
| 241 | <li>By default, RPC calls are synchronous. If you know that the service takes more than a few |
| 242 | milliseconds to complete a request, you should not call it from the activity's main thread, because |
| 243 | it might hang the application (Android might display an "Application is Not Responding" |
| 244 | dialog)—you should usually call them from a separate thread in the client. </li> |
| 245 | <li>No exceptions that you throw are sent back to the caller.</li> |
| 246 | </ul> |
| 247 | |
| 248 | |
| 249 | <h3 id="Expose">3. Expose the interface to clients</h3> |
| 250 | |
| 251 | <p>Once you've implemented the interface for your service, you need to expose it to |
| 252 | clients so they can bind to it. To expose the interface |
| 253 | for your service, extend {@link android.app.Service Service} and implement {@link |
| 254 | android.app.Service#onBind onBind()} to return an instance of your class that implements |
| 255 | the generated {@code Stub} (as discussed in the previous section). Here's an example |
| 256 | service that exposes the {@code IRemoteService} example interface to clients. </p> |
| 257 | |
| 258 | <pre> |
| 259 | public class RemoteService extends Service { |
| 260 | @Override |
| 261 | public void onCreate() { |
| 262 | super.onCreate(); |
| 263 | } |
| 264 | |
| 265 | @Override |
| 266 | public IBinder onBind(Intent intent) { |
| 267 | // Return the interface |
| 268 | return mBinder; |
| 269 | } |
| 270 | |
| 271 | private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { |
| 272 | public int getPid(){ |
| 273 | return Process.myPid(); |
| 274 | } |
| 275 | public void basicTypes(int anInt, long aLong, boolean aBoolean, |
| 276 | float aFloat, double aDouble, String aString) { |
| 277 | // Does nothing |
| 278 | } |
| 279 | }; |
| 280 | } |
| 281 | </pre> |
| 282 | |
| 283 | <p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService |
| 284 | bindService()} to connect to this service, the client's {@link |
| 285 | android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the |
| 286 | {@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()} |
| 287 | method.</p> |
| 288 | |
| 289 | <p>The client must also have access to the interface class, so if the client and service are in |
| 290 | separate applications, then the client's application must have a copy of the {@code .aidl} file |
| 291 | in its {@code src/} directory (which generates the {@code android.os.Binder} |
| 292 | interface—providing the client access to the AIDL methods).</p> |
| 293 | |
| 294 | <p>When the client receives the {@link android.os.IBinder} in the {@link |
| 295 | android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call |
| 296 | <code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned |
| 297 | parameter to <code><em>YourServiceInterface</em></code> type. For example:</p> |
| 298 | |
| 299 | <pre> |
| 300 | IRemoteService mIRemoteService; |
| 301 | private ServiceConnection mConnection = new ServiceConnection() { |
| 302 | // Called when the connection with the service is established |
| 303 | public void onServiceConnected(ComponentName className, IBinder service) { |
| 304 | // Following the example above for an AIDL interface, |
| 305 | // this gets an instance of the IRemoteInterface, which we can use to call on the service |
| 306 | mIRemoteService = IRemoteService.Stub.asInterface(service); |
| 307 | } |
| 308 | |
| 309 | // Called when the connection with the service disconnects unexpectedly |
| 310 | public void onServiceDisconnected(ComponentName className) { |
| 311 | Log.e(TAG, "Service has unexpectedly disconnected"); |
| 312 | mIRemoteService = null; |
| 313 | } |
| 314 | }; |
| 315 | </pre> |
| 316 | |
| 317 | <p>For more sample code, see the <a |
| 318 | href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code |
| 319 | RemoteService.java}</a> class in <a |
| 320 | href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p> |
| 321 | |
| 322 | |
| 323 | |
| 324 | |
| 325 | |
| 326 | |
| 327 | |
| 328 | |
| 329 | <h2 id="PassingObjects">Passing Objects over IPC</h2> |
| 330 | |
| 331 | <p>If you have a class that you would like to send from one process to another through |
| 332 | an IPC interface, you can do that. However, you must ensure that the code for your class is |
| 333 | available to the other side of the IPC channel and your class must support the {@link |
| 334 | android.os.Parcelable} interface. Supporting the {@link android.os.Parcelable} interface is |
| 335 | important because it allows the Android system to decompose objects into primitives that can be |
| 336 | marshalled across processes.</p> |
| 337 | |
| 338 | <p>To create a class that supports the {@link android.os.Parcelable} protocol, you must do the |
| 339 | following:</b> |
| 340 | <ol> |
| 341 | <li>Make your class implement the {@link android.os.Parcelable} interface.</li> |
| 342 | <li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the |
| 343 | current state of the object and writes it to a {@link android.os.Parcel}.</li> |
| 344 | <li>Add a static field called <code>CREATOR</code> to your class which is an object implementing |
| 345 | the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li> |
| 346 | <li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the |
| 347 | {@code Rect.aidl} file, below). |
| 348 | <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your |
| 349 | build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li> |
| 350 | </ol> |
| 351 | |
| 352 | <p>AIDL uses these methods and fields in the code it generates to marshall and unmarshall |
| 353 | your objects.</p> |
| 354 | |
| 355 | <p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's |
| 356 | parcelable:</p> |
| 357 | |
| 358 | <pre> |
| 359 | package android.graphics; |
| 360 | |
| 361 | // Declare Rect so AIDL can find it and knows that it implements |
| 362 | // the parcelable protocol. |
| 363 | parcelable Rect; |
| 364 | </pre> |
| 365 | |
| 366 | <p>And here is an example of how the {@link android.graphics.Rect} class implements the |
| 367 | {@link android.os.Parcelable} protocol.</p> |
| 368 | |
| 369 | <pre> |
| 370 | import android.os.Parcel; |
| 371 | import android.os.Parcelable; |
| 372 | |
| 373 | public final class Rect implements Parcelable { |
| 374 | public int left; |
| 375 | public int top; |
| 376 | public int right; |
| 377 | public int bottom; |
| 378 | |
| 379 | public static final Parcelable.Creator<Rect> CREATOR = new |
| 380 | Parcelable.Creator<Rect>() { |
| 381 | public Rect createFromParcel(Parcel in) { |
| 382 | return new Rect(in); |
| 383 | } |
| 384 | |
| 385 | public Rect[] newArray(int size) { |
| 386 | return new Rect[size]; |
| 387 | } |
| 388 | }; |
| 389 | |
| 390 | public Rect() { |
| 391 | } |
| 392 | |
| 393 | private Rect(Parcel in) { |
| 394 | readFromParcel(in); |
| 395 | } |
| 396 | |
| 397 | public void writeToParcel(Parcel out) { |
| 398 | out.writeInt(left); |
| 399 | out.writeInt(top); |
| 400 | out.writeInt(right); |
| 401 | out.writeInt(bottom); |
| 402 | } |
| 403 | |
| 404 | public void readFromParcel(Parcel in) { |
| 405 | left = in.readInt(); |
| 406 | top = in.readInt(); |
| 407 | right = in.readInt(); |
| 408 | bottom = in.readInt(); |
| 409 | } |
| 410 | } |
| 411 | </pre> |
| 412 | |
| 413 | <p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other |
| 414 | methods on {@link android.os.Parcel} to see the other kinds of values you can write |
| 415 | to a Parcel.</p> |
| 416 | |
| 417 | <p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving |
| 418 | data from other processes. In this case, the {@code Rect} reads four numbers from the {@link |
| 419 | android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of |
| 420 | values for whatever the caller is trying to do. See <a |
| 421 | href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more |
| 422 | information about how to keep your application secure from malware.</p> |
| 423 | |
| 424 | |
| 425 | |
| 426 | <h2 id="Calling">Calling an IPC Method</h2> |
| 427 | |
| 428 | <p>Here are the steps a calling class must take to call a remote interface defined with AIDL: </p> |
| 429 | <ol> |
| 430 | <li>Include the {@code .aidl} file in the project {@code src/} directory.</li> |
| 431 | <li>Declare an instance of the {@link android.os.IBinder} interface (generated based on the |
| 432 | AIDL). </li> |
| 433 | <li>Implement {@link android.content.ServiceConnection ServiceConnection}. </li> |
| 434 | <li>Call {@link |
| 435 | android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int) |
| 436 | Context.bindService()}, passing in your {@link |
| 437 | android.content.ServiceConnection} implementation. </li> |
| 438 | <li>In your implementation of {@link |
| 439 | android.content.ServiceConnection#onServiceConnected onServiceConnected()}, |
| 440 | you will receive an {@link android.os.IBinder} instance (called <code>service</code>). Call |
| 441 | <code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to |
| 442 | cast the returned parameter to <em>YourInterface</em> type.</li> |
| 443 | <li>Call the methods that you defined on your interface. You should always trap |
| 444 | {@link android.os.DeadObjectException} exceptions, which are thrown when |
| 445 | the connection has broken; this will be the only exception thrown by remote |
| 446 | methods.</li> |
| 447 | <li>To disconnect, call {@link |
| 448 | android.content.Context#unbindService(android.content.ServiceConnection) |
| 449 | Context.unbindService()} with the instance of your interface. </li> |
| 450 | </ol> |
| 451 | <p>A few comments on calling an IPC service:</p> |
| 452 | <ul> |
| 453 | <li>Objects are reference counted across processes. </li> |
| 454 | <li>You can send anonymous objects |
| 455 | as method arguments. </li> |
| 456 | </ul> |
| 457 | |
| 458 | <p>For more information about binding to a service, read the <a |
| 459 | href="{@docRoot}guide/components/bound-services.html#Binding">Bound Services</a> |
| 460 | document.</p> |
| 461 | |
| 462 | <p>Here is some sample code demonstrating calling an AIDL-created service, taken |
| 463 | from the Remote Service sample in the ApiDemos project.</p> |
| 464 | <p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java |
| 465 | calling_a_service}</p> |