• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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        &mdash; 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&lt;String&gt;).
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&lt;String,Integer&gt;
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&lt;String&gt; 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 &quot;Application
167        is Not Responding&quot; 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 &quot;publishing your service.&quot; 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&lt;Rect&gt; CREATOR = new Parcelable.Creator&lt;Rect&gt;() {
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