summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorScott Main <smain@google.com>2011-02-18 15:14:44 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-02-18 15:14:44 -0800
commit375adc69aedbfe8bf73fa9782d57522927d502e4 (patch)
tree1de0025c00508c0fd8985bf1f0303a969637ceb2 /docs
parenta4738cf78fb9a0203d3f223fad6cdc98cff7ec30 (diff)
parent483f7130b593bb79f8ad0740356963aab42ccf54 (diff)
downloadframeworks_base-375adc69aedbfe8bf73fa9782d57522927d502e4.zip
frameworks_base-375adc69aedbfe8bf73fa9782d57522927d502e4.tar.gz
frameworks_base-375adc69aedbfe8bf73fa9782d57522927d502e4.tar.bz2
am 483f7130: am e4da3934: Merge "docs: move new AIDL doc back into the existing doc, but move the side nav location out of tools" into honeycomb
* commit '483f7130b593bb79f8ad0740356963aab42ccf54': docs: move new AIDL doc back into the existing doc, but move the side nav location out of tools
Diffstat (limited to 'docs')
-rw-r--r--docs/html/guide/developing/tools/aidl.jd556
-rw-r--r--docs/html/guide/guide_toc.cs2
-rw-r--r--docs/html/guide/topics/advanced/aidl.jd389
-rw-r--r--docs/html/guide/topics/fundamentals/bound-services.jd4
4 files changed, 361 insertions, 590 deletions
diff --git a/docs/html/guide/developing/tools/aidl.jd b/docs/html/guide/developing/tools/aidl.jd
index d3da285..731aef7 100644
--- a/docs/html/guide/developing/tools/aidl.jd
+++ b/docs/html/guide/developing/tools/aidl.jd
@@ -1,4 +1,4 @@
-page.title=Designing a Remote Interface Using AIDL
+page.title=Android Interface Definition Language (AIDL)
@jd:body
@@ -6,209 +6,367 @@ page.title=Designing a Remote Interface Using AIDL
<div id="qv">
<h2>In this document</h2>
<ol>
- <li><a href="#implementing">Implementing IPC Using AIDL</a>
+ <li><a href="#Defining">Defining an AIDL Interface</a>
<ol>
- <li><a href="#aidlsyntax">Create an .aidl File</a></li>
- <li><a href="#implementtheinterface">Implementing the Interface</a></li>
- <li><a href="#exposingtheinterface">Exposing Your Interface to Clients</a></li>
- <li><a href="#parcelable">Pass by value Parameters using Parcelables</a></li>
+ <li><a href="#Create">Create the .aidl file</a></li>
+ <li><a href="#Implement">Implement the interface</a></li>
+ <li><a href="#Expose">Expose the interface to clients</a></li>
</ol>
</li>
- <li><a href="#calling">Calling an IPC Method</a></li>
+ <li><a href="#PassingObjects">Passing Objects over IPC</a></li>
+ <li><a href="#Calling">Calling an IPC Method</a></li>
</ol>
+
+<h2>See also</h2>
+<ol>
+ <li><a href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a></li>
+</ol>
+
</div>
</div>
-<p>Since each application runs in its own process, and you can write a service that
-runs in a different process from your Application's UI, sometimes you need to pass objects
-between processes. On the Android platform, one process can not normally access the memory
-of another process. So to talk, they need to decompose their objects into primitives that
-the operating system can understand, and "marshall" the object across that boundary for you.</p>
+<p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have
+worked with. It allows you to define the programming interface that both
+the client and service agree upon in order to communicate with each other using
+interprocess communication (IPC). On Android, one process cannot normally access the
+memory of another process. So to talk, they need to decompose their objects into primitives that the
+operating system can understand, and marshall the objects across that boundary for you. The code to
+do that marshalling is tedious to write, so Android handles it for you with AIDL.</p>
+
+<p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from
+different applications to access your service for IPC and want to handle multithreading in your
+service. If you do not need to perform concurrent IPC across
+different applications, you should create your interface by <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
+Binder</a> or, if you want to perform IPC, but do <em>not</em> need to handle multithreading,
+implement your interface <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Messenger">using a Messenger</a>.
+Regardless, be sure that you understand <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a> before
+implementing an AIDL.</p>
+
+<p>Before you begin designing your AIDL interface, be aware that calls to an AIDL interface are
+direct function calls. You should not make assumptions about the thread in which the call
+occurs. What happens is different depending on whether the call is from a thread in the
+local process or a remote process. Specifically:</p>
-<p>The code to do that marshalling is tedious to write, so we provide the AIDL tool to do it
-for you.</p>
+<ul>
+<li>Calls made from the local process are executed in the same thread that is making the call. If
+this is your main UI thread, that thread continues to execute in the AIDL interface. If it is
+another thread, that is the one that executes your code in the service. Thus, if only local
+threads are accessing the service, you can completely control which threads are executing in it (but
+if that is the case, then you shouldn't be using AIDL at all, but should instead create the
+interface by <a href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
+Binder</a>).</li>
+
+<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
+your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
+happening at the same time. In other words, an implementation of an AIDL interface must be
+completely thread-safe.</li>
+
+<li>The {@code oneway} keyword modifies the behavior of remote calls. When used, a remote call does
+not block; it simply sends the transaction data and immediately returns.
+The implementation of the interface eventually receives this as a regular call from the {@link
+android.os.Binder} thread pool as a normal remote call. If {@code oneway} is used with a local call,
+there is no impact and the call is still synchronous.</li>
+</ul>
-<p>AIDL (Android Interface Definition Language) is an <a
-href="http://en.wikipedia.org/wiki/Interface_description_language">IDL</a>
-language used to generate code that enables two processes on an Android-powered device
-to talk using interprocess communication (IPC). If you have code
-in one process (for example, in an Activity) that needs to call methods on an
-object in another process (for example, a Service), you would use AIDL to
-generate code to marshall the parameters.</p>
-<p>The AIDL IPC mechanism
- is interface-based, similar to COM or Corba, but lighter weight. It uses a proxy
- class to pass values between the client and the implementation. </p>
+<h2 id="Defining">Defining an AIDL Interface</h2>
-<h2 id="implementing">Implementing IPC Using AIDL</h2>
-<p>Follow these steps to implement an IPC service using AIDL.</p>
+<p>You must define your AIDL interface in an {@code .aidl} file using the Java
+programming language syntax, then save it in the source code (in the {@code src/} directory) of both
+the application hosting the service and any other application that binds to the service.</p>
+
+<p>When you build each application that contains the {@code .aidl} file, the Android SDK tools
+generate an {@link android.os.IBinder} interface based on the {@code .aidl} file and save it in
+the project's {@code gen/} directory. The service must implement the {@link android.os.IBinder}
+interface as appropriate. The client applications can then bind to the service and call methods from
+the {@link android.os.IBinder} to perform IPC.</p>
+
+<p>To create a bounded service using AIDL, follow these steps:</p>
<ol>
- <li><strong><a href="#aidlsyntax">Create your .aidl file</a> </strong>- This
- file defines an interface (<em>YourInterface</em>.aidl) that defines the
- methods and fields available to a client. </li>
- <li><strong>Add the .aidl file to your makefile</strong> - (the ADT Plugin for Eclipse
- manages this for you). Android includes the compiler, called
- AIDL, in the <code>tools/</code> directory. </li>
- <li><strong><a href="#implementtheinterface">Implement your interface methods</a></strong> -
- The AIDL compiler creates an interface in the Java programming language from your AIDL interface.
- This interface has an inner abstract class named Stub that inherits the
- interface (and implements a few additional methods necessary for the IPC
- call). You must create a class that extends <em>YourInterface</em>.Stub
- and implements the methods you declared in your .aidl file. </li>
- <li><strong><a href="#exposingtheinterface">Expose your interface to clients</a></strong> -
- If you're writing a service, you should extend {@link
- android.app.Service Service} and override {@link android.app.Service#onBind
- Service.onBind(Intent)} to return an instance of your class that implements your
- interface. </li>
+ <li><a href="#CreateAidl">Create the .aidl file</a>
+ <p>This file defines the programming interface with method signatures.</p>
+ </li>
+ <li><a href="#ImplementTheInterface">Implement the interface</a>
+ <p>The Android SDK tools generate an interface in the Java programming language, based on your
+{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
+{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
+{@code Stub} class and implement the methods.</p>
+ </li>
+ <li><a href="#ExposeTheInterface">Expose the interface to clients</a>
+ <p>Implement a {@link android.app.Service Service} and override {@link
+android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
+class.</p>
+ </li>
</ol>
-<h3 id="aidlsyntax">Create an .aidl File</h3>
-<p>AIDL is a simple syntax that lets you declare an interface with one or more
- methods, that can take parameters and return values. These parameters and return
- values can be of any type, even other AIDL-generated interfaces. <em>However, it
- is important to note</em> that you <em>must</em> import all non-built-in types,
- <em>even if they are defined in the same package as your interface</em>.
- Here are the data types that AIDL can support: </p>
+<p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after
+your first release must remain backward compatible in order to avoid breaking other applications
+that use your service. That is, because your {@code .aidl} file must be copied to other applications
+in order for them to access your service's interface, you must maintain support for the original
+interface.</p>
+
+
+<h3 id="Create">1. Create the .aidl file</h3>
+
+<p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
+take parameters and return values. The parameters and return values can be of any type, even other
+AIDL-generated interfaces.</p>
+
+<p>You must construct the {@code .aidl} file using the Java programming language. Each {@code .aidl}
+file must define a single interface and requires only the interface declaration and method
+signatures.</p>
+
+<p>By default, AIDL supports the following data types:</p>
+
<ul>
- <li>Primitive Java programming language types (int, boolean, etc)
- &mdash; No <code>import</code> statement is needed. </li>
- <li>One of the following classes (no <code>import</code> statements needed):
- <ul>
- <li><strong>String</strong></li>
- <li><strong>List</strong> - All elements in the List must be one of the types
- in this list, including other AIDL-generated interfaces and
- parcelables. List may optionally be used as a "generic" class (e.g.
- List&lt;String&gt;).
- The actual concrete class that the other side will receive
- will always be an ArrayList, although the method will be generated
- to use the List interface. </li>
- <li><strong>Map</strong> - All elements in the Map must be of one of the
- types in this list, including other AIDL-generated interfaces and
- parcelables. Generic maps, (e.g. of the form Map&lt;String,Integer&gt;
- are not supported.
- The actual concrete class that the other side will receive
- will always be a HashMap, although the method will be generated
- to use the Map interface.</li>
- <li><strong>CharSequence</strong> - This is useful for the CharSequence
- types used by {@link android.widget.TextView TextView} and other
- widget objects. </li>
- </ul>
- </li>
- <li>Other AIDL-generated interfaces, which are always passed by reference.
- An <code>import</code> statement is always needed for these.</li>
- <li>Custom classes that implement the <a href="#parcelable">Parcelable
- protocol</a> and are passed by value.
- An <code>import</code> statement is always needed for these.</li>
+ <li>All primitive types in the Java programming language (such as {@code int}, {@code long},
+{@code char}, {@code boolean}, and so on)</li>
+ <li>{@link java.lang.String}</li>
+ <li>{@link java.lang.CharSequence}</li>
+ <li>{@link java.util.List}
+ <p>All elements in the {@link java.util.List} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
+java.util.List} may optionally be used as a "generic" class (for example,
+<code>List&lt;String&gt;</code>).
+The actual concrete class that the other side receives is always an {@link
+java.util.ArrayList}, although the method is generated to use the {@link
+java.util.List} interface.</p>
+ </li>
+ <li>{@link java.util.Map}
+ <p>All elements in the {@link java.util.Map} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
+(such as those of the form
+{@code Map&lt;String,Integer&gt;} are not supported. The actual concrete class that the other side
+receives is always a {@link java.util.HashMap}, although the method is generated to
+use the {@link java.util.Map} interface.</p>
+ </li>
</ul>
-<p>Here is the basic AIDL syntax:</p>
-<pre>// My AIDL file, named <em>SomeClass</em>.aidl
-// Note that standard comment syntax is respected.
-// Comments before the import or package statements are not bubbled up
-// to the generated interface, but comments above interface/method/field
-// declarations are added to the generated interface.
-
-// Include your fully-qualified package statement.
-package com.android.sample;
-
-// See the list above for which classes need
-// import statements (hint--most of them)
-import com.android.sample.IAtmService;
-
-// Declare the interface.
-interface IBankAccountService {
-
- // Methods can take 0 or more parameters, and
- // return a value or void.
- int getAccountBalance();
- void setOwnerNames(in List&lt;String&gt; names);
-
- // Methods can even take other AIDL-defined parameters.
- BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);
-
- // All non-Java primitive parameters (e.g., int, bool, etc) require
- // a directional tag indicating which way the data will go. Available
- // values are in, out, inout. (Primitives are in by default, and cannot be otherwise).
- // Limit the direction to what is truly needed, because marshalling parameters
- // is expensive.
- int getCustomerList(in String branch, out String[] customerList);
-}</pre>
-
-<h3 id="implementtheinterface">Implementing the Interface</h3>
-<p>AIDL generates an interface file for you with the same name as your .aidl
- file. If you are using the Eclipse plugin, AIDL will automatically be run as part of
- the build process (you don't need to run AIDL first and then build your project).
- If you are not using the plugin, you should run AIDL first. </p>
-<p>The generated interface
- includes an abstract inner class named Stub that declares all the methods
- that you declared in your .aidl file. Stub also defines a few helper methods,
- most notably asInterface(), which takes an IBinder (passed to a client's onServiceConnected()
- implementation when applicationContext.bindService() succeeds), and returns an
- instance of the interface used to call the IPC methods. See the section
- <a href="#calling">Calling an IPC Method</a> for more details on how to make this cast.</p>
-<p>To implement your interface, extend <em>YourInterface</em>.Stub,
- and implement the methods. (You can create the .aidl file and implement the stub
- methods without building between--the Android build process will process .aidl
-files before .java files.) </p>
-<p>Here is an example of implementing an interface called IRemoteService, which exposes
- a single method, getPid(), using an anonymous instance:</p>
-<pre>// No need to import IRemoteService if it's in the same project.
-private final IRemoteService.Stub mBinder = new IRemoteService.Stub(){
+
+<p>You must include an {@code import} statement for each additional type not listed above, even if
+they are defined in the same package as your interface.</p>
+
+<p>When defining your service interface, be aware that:</p>
+<ul>
+ <li>Methods can take zero or more parameters, and return a value or void.</li>
+ <li>All non-primitive parameters require a directional tag indicating which way the data goes.
+Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
+ <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
+ <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
+needed, because marshalling parameters is expensive.</p></li>
+ <li>All code comments included in the {@code .aidl} file are included in the generated {@link
+android.os.IBinder} interface (except for comments before the import and package
+statements).</li>
+ <li>Only methods are supported; you cannot expose static fields in AIDL.</li>
+</ul>
+
+<p>Here is an example {@code .aidl} file:</p>
+
+<pre>
+// IRemoteService.aidl
+package com.example.android;
+
+// Declare any non-default types here with import statements
+
+/** Example service interface */
+interface IRemoteService {
+ /** Request the process ID of this service, to do evil things with it. */
+ int getPid();
+
+ /** Demonstrates some basic types that you can use as parameters
+ * and return values in AIDL.
+ */
+ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+ double aDouble, String aString);
+}
+</pre>
+
+<p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
+build your application, the SDK tools generate the {@link android.os.IBinder} interface file in your
+project's {@code gen/} directory. The generated file name matches the {@code .aidl} file name, but
+with a {@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
+IRemoteService.java}).</p>
+
+<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
+do not use Eclipse, then the Ant tool generates the binder class next time you build your
+application&mdash;you should build your project with <code>ant debug</code> (or <code>ant
+release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
+link against the generated class.</p>
+
+
+<h3 id="Implement">2. Implement the interface</h3>
+
+<p>When you build your application, the Android SDK tools generate a {@code .java} interface file
+named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
+that is an abstract implementation of its parent interface (for example, {@code
+YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p>
+
+<p class="note"><strong>Note:</strong> {@code Stub} also
+defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
+android.os.IBinder} (usually the one passed to a client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
+returns an instance of the stub interface. See the section <a href="#calling">Calling an IPC
+Method</a> for more details on how to make this cast.</p>
+
+<p>To implement the interface generated from the {@code .aidl}, extend the generated {@link
+android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods
+inherited from the {@code .aidl} file.</p>
+
+<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
+{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
+
+<pre>
+private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
public int getPid(){
return Process.myPid();
}
-}</pre>
-<p>A few rules about implementing your interface: </p>
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+};
+</pre>
+
+<p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}),
+which defines the RPC interface for the service. In the next step, this instance is exposed to
+clients so they can interact with the service.</p>
+
+<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
<ul>
- <li>No exceptions that you throw will be sent back to the caller.</li>
- <li>By default, IPC calls are synchronous. If you know that an IPC service takes more than
- a few milliseconds to complete, you should not call it in the Activity/View thread,
- because it might hang the application (Android might display an &quot;Application
- is Not Responding&quot; dialog).
- Try to call them in a separate thread. </li>
- <li>Only methods are supported; you cannot declare static fields in an AIDL interface.</li>
+ <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
+about multithreading from the start and properly build your service to be thread-safe.</li>
+ <li>By default, RPC calls are synchronous. If you know that the service takes more than a few
+milliseconds to complete a request, you should not call it from the activity's main thread, because
+it might hang the application (Android might display an &quot;Application is Not Responding&quot;
+dialog)&mdash;you should usually call them from a separate thread in the client. </li>
+ <li>No exceptions that you throw are sent back to the caller.</li>
</ul>
-<h3 id="exposingtheinterface">Exposing Your Interface to Clients</h3>
-<p>Now that you've got your interface implementation, you need to expose it to clients.
- This is known as &quot;publishing your service.&quot; To publish a service,
- inherit {@link android.app.Service Service} and implement {@link android.app.Service#onBind
- Service.onBind(Intent)} to return an instance of the class that implements your interface.
- Here's a code snippet of a service that exposes the IRemoteService
- interface to clients. </p>
-<pre>public class RemoteService extends Service {
-...
-{@include development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
- exposing_a_service}
-}</pre>
+<h3 id="Expose">3. Expose the interface to clients</h3>
+
+<p>Once you've implemented the interface for your service, you need to expose it to
+clients so they can bind to it. To expose the interface
+for your service, extend {@link android.app.Service Service} and implement {@link
+android.app.Service#onBind onBind()} to return an instance of your class that implements
+the generated {@code Stub} (as discussed in the previous section). Here's an example
+service that exposes the {@code IRemoteService} example interface to clients. </p>
+
+<pre>
+public class RemoteService extends Service {
+ &#64;Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ // Return the interface
+ return mBinder;
+ }
+
+ private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+ public int getPid(){
+ return Process.myPid();
+ }
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+ };
+}
+</pre>
+
+<p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService
+bindService()} to connect to this service, the client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the
+{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()}
+method.</p>
+
+<p>The client must also have access to the interface class, so if the client and service are in
+separate applications, then the client's application must have a copy of the {@code .aidl} file
+in its {@code src/} directory (which generates the {@code android.os.Binder}
+interface&mdash;providing the client access to the AIDL methods).</p>
+
+<p>When the client receives the {@link android.os.IBinder} in the {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
+<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
+parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
+
+<pre>
+IRemoteService mIRemoteService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Following the example above for an AIDL interface,
+ // this gets an instance of the IRemoteInterface, which we can use to call on the service
+ mIRemoteService = IRemoteService.Stub.asInterface(service);
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "Service has unexpectedly disconnected");
+ mIRemoteService = null;
+ }
+};
+</pre>
-<h3 id="parcelable">Pass by value Parameters using Parcelables</h3>
+<p>For more sample code, see the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+RemoteService.java}</a> class in <a
+href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
+
+
+
+
+
+
+
+
+<h2 id="PassingObjects">Passing Objects over IPC</h2>
<p>If you have a class that you would like to send from one process to another through
-an AIDL interface, you can do that. You must ensure that the code for your class is available
-to the other side of the IPC. Generally, that means that you're talking to a service that you
-started.</p>
-<p>There are five parts to making a class support the Parcelable protocol:</b>
+an IPC interface, you can do that. However, you must ensure that the code for your class is
+available to the other side of the IPC channel and your class must support the {@link
+android.os.Parcelable} interface. Supporting the {@link android.os.Parcelable} interface is
+important because it allows the Android system to decompose objects into primitives that can be
+marshalled across processes.</p>
+
+<p>To create a class that supports the {@link android.os.Parcelable} protocol, you must do the
+following:</b>
<ol>
<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
-<li>Implement the method <code>public void writeToParcel(Parcel out)</code> that takes the
-current state of the object and writes it to a parcel.</li>
-value in a parcel into your object.</li>
+<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
+current state of the object and writes it to a {@link android.os.Parcel}.</li>
<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
-<li>Last but not least, create an aidl file
-that declares your parcelable class (as shown below). If you are using a custom build process,
-do not add the aidl file to your build. Similar to a header file in C, the aidl file isn't
-compiled.</li>
+<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
+{@code Rect.aidl} file, below).
+ <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
+build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
</ol>
-<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
+<p>AIDL uses these methods and fields in the code it generates to marshall and unmarshall
your objects.</p>
-<p>Here is an example of how the {@link android.graphics.Rect} class implements the
-Parcelable protocol.</p>
-<pre class="prettyprint">
+<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
+parcelable:</p>
+
+<pre>
+package android.graphics;
+
+// Declare Rect so AIDL can find it and knows that it implements
+// the parcelable protocol.
+parcelable Rect;
+</pre>
+
+<p>And here is an example of how the {@link android.graphics.Rect} class implements the
+{@link android.os.Parcelable} protocol.</p>
+
+<pre>
import android.os.Parcel;
import android.os.Parcelable;
@@ -218,7 +376,8 @@ public final class Rect implements Parcelable {
public int right;
public int bottom;
- public static final Parcelable.Creator&lt;Rect&gt; CREATOR = new Parcelable.Creator&lt;Rect&gt;() {
+ public static final Parcelable.Creator&lt;Rect&gt; CREATOR = new
+Parcelable.Creator&lt;Rect&gt;() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
@@ -251,43 +410,42 @@ public final class Rect implements Parcelable {
}
</pre>
-<p>Here is Rect.aidl for this example</p>
+<p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other
+methods on {@link android.os.Parcel} to see the other kinds of values you can write
+to a Parcel.</p>
-<pre class="prettyprint">
-package android.graphics;
+<p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving
+data from other processes. In this case, the {@code Rect} reads four numbers from the {@link
+android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of
+values for whatever the caller is trying to do. See <a
+href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
+information about how to keep your application secure from malware.</p>
-// Declare Rect so AIDL can find it and knows that it implements
-// the parcelable protocol.
-parcelable Rect;
-</pre>
-<p>The marshalling in the Rect class is pretty simple. Take a look at the other
-methods on {@link android.os.Parcel} to see the other kinds of values you can write
-to a Parcel.</p>
-<p class="warning"><b>Warning:</b> Don't forget the security implications of receiving data from
-other processes. In this case, the rect will read four numbers from the parcel,
-but it is up to you to ensure that these are within the acceptable range of
-values for whatever the caller is trying to do. See
-<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
-on how to keep your application secure from malware.</p>
+<h2 id="Calling">Calling an IPC Method</h2>
-<h2 id="calling">Calling an IPC Method</h2>
-<p>Here are the steps a calling class should make to call your remote interface: </p>
+<p>Here are the steps a calling class must take to call a remote interface defined with AIDL: </p>
<ol>
- <li>Declare a variable of the interface type that your .aidl file defined. </li>
+ <li>Include the {@code .aidl} file in the project {@code src/} directory.</li>
+ <li>Declare an instance of the {@link android.os.IBinder} interface (generated based on the
+AIDL). </li>
<li>Implement {@link android.content.ServiceConnection ServiceConnection}. </li>
- <li>Call {@link android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int)
- Context.bindService()}, passing in your ServiceConnection implementation. </li>
- <li>In your implementation of {@link android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,android.os.IBinder)
- ServiceConnection.onServiceConnected()}, you will receive an {@link android.os.IBinder
- IBinder} instance (called <em>service</em>). Call <code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to
+ <li>Call {@link
+android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int)
+ Context.bindService()}, passing in your {@link
+android.content.ServiceConnection} implementation. </li>
+ <li>In your implementation of {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()},
+you will receive an {@link android.os.IBinder} instance (called <code>service</code>). Call
+<code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to
cast the returned parameter to <em>YourInterface</em> type.</li>
<li>Call the methods that you defined on your interface. You should always trap
{@link android.os.DeadObjectException} exceptions, which are thrown when
the connection has broken; this will be the only exception thrown by remote
methods.</li>
- <li>To disconnect, call {@link android.content.Context#unbindService(android.content.ServiceConnection)
+ <li>To disconnect, call {@link
+android.content.Context#unbindService(android.content.ServiceConnection)
Context.unbindService()} with the instance of your interface. </li>
</ol>
<p>A few comments on calling an IPC service:</p>
@@ -296,10 +454,12 @@ on how to keep your application secure from malware.</p>
<li>You can send anonymous objects
as method arguments. </li>
</ul>
+
+<p>For more information about binding to a service, read the <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binding">Bound Services</a>
+document.</p>
+
<p>Here is some sample code demonstrating calling an AIDL-created service, taken
from the Remote Service sample in the ApiDemos project.</p>
<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
calling_a_service}</p>
-
-
-
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 92230a9..d81b416 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -554,7 +554,6 @@
<ul>
<li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/android.html">android</a></li>
- <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
<li><a href="<?cs var:toroot ?>guide/developing/tools/dmtracedump.html">dmtracedump</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html" >Draw 9-Patch</a></li>
@@ -754,6 +753,7 @@
<li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
<span class="en">Intents List: Google Apps</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">AIDL</a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/glossary.html">
<span class="en">Glossary</span>
</a></li>
diff --git a/docs/html/guide/topics/advanced/aidl.jd b/docs/html/guide/topics/advanced/aidl.jd
deleted file mode 100644
index 419048a..0000000
--- a/docs/html/guide/topics/advanced/aidl.jd
+++ /dev/null
@@ -1,389 +0,0 @@
-page.title=Android Interface Definition Language (AIDL)
-@jd:body
-
-
-
-<p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have
-worked with. It allows you to define the programming interface that both
-the client and service agree upon in order to communicate with each other and allows for
-interprocess communication (IPC). On Android, one process can not normally access the
-memory of another process. So to talk, they need to decompose their objects into primitives that the
-operating system can understand, and "marshall" the object across that boundary for you. The code to
-do that marshalling is tedious to write, so Android handles it for you with AIDL.</p>
-
-<p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from
-different applications to access your service for IPC and want to handle multithreading in your
-service. If you do not need to perform IPC across
-different applications, you should create your interface <a
-href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
-Binder</a> or, if you want to perform IPC, but do not need to handle multithreading, then you
-should implement your interface <a
-href="{@docRoot}guide/topics/fundamentals/bound-services.html#Messenger">using a Messenger</a>.</p>
-
-<p>Before you begin designing your AIDL interface, be aware that calls on to an AIDL interface are
-direct function calls. You can not generally make assumptions about the thread in which the call
-will happen. What happens is different depending on whether the call is from a thread in the
-local process, or coming from a remote process. Specifically:</p>
-
-<ul>
-<li>Calls from the local process are executed in the same thread that is making the call. If this is
-your main UI thread, that thread will continue executing into the aidl interface. If it is another
-thread, that is one that will be executing your code. Thus if only local threads are accessing the
-interface, you can completely control which threads are executing in it (but if that is the case,
-why are you defining an aidl interface at all?).</li>
-
-<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
-your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
-happening at the same time. In other words, an implementation of an aidl interface must be
-completely thread-safe.</li>
-
-<li>The "oneway" keyword modifies the behavior of remote calls. When used, a remote call will not
-block until its call completes; it simply sends the transaction data and immediately returns. The
-implementation of the interface will eventually receive this as a regular call from the {@link
-android.os.Binder} thread pool as a normal remote call. If "oneway" is used with a local call,
-there is no impact and the call is still synchronous.</li>
-</ul>
-
-
-<h2 id="Defining">Defining an AIDL Interface</h2>
-
-<p>You must define your AIDL interface in an {@code .aidl} file using the Java
-programming language syntax, then save it in the source code (in the {@code src/} directory) of both
-the application hosting the service and any other application that will bind to the service.</p>
-
-<p>When you build the projects containing the {@code .aidl} file, the Android SDK tools generate an
-{@link android.os.IBinder} class based on your AIDL interface (and saves the file in the {@code
-gen/} directory). This class defines the APIs you can call to perform RPC as an interface&mdash;you
-must implement the interface in your service.</p>
-
-<p>To create a bounded service using AIDL, follow these steps:</p>
-<ol>
- <li><a href="#CreateAidl">Create the .aidl file</a>
- <p>This file defines the programming interface with method signatures.</p>
- </li>
- <li><a href="#ImplementTheInterface">Implement the interface</a>
- <p>The Android SDK tools generate an interface in the Java programming language, based on your
-{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
-{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
-{@code Stub} class and implement the methods.</p>
- </li>
- <li><a href="#ExposeTheInterface">Expose the interface to clients</a>
- <p>Implement a {@link android.app.Service Service} and override {@link
-android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
-class.</p>
- </li>
-</ol>
-
-<p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after
-your first release must remain backward compatible in order to avoid breaking other applications
-that use your service. That is, because your {@code .aidl} file must be copied to other applications
-in order for them to access your service's interface, you must maintain support for the original
-interface.</p>
-
-
-<h3 id="CreateAidl">1. Create the .aidl file</h3>
-
-<p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
-take parameters and return values. The parameters and return values can be of any type, even other
-AIDL-generated interfaces.</p>
-
-<p>The syntax for the {@code .aidl} file uses the Java programming language. The file defines a
-single interface and requires only the interface declaration and method signatures.</p>
-
-<p>By default, AIDL supports the following data types:</p>
-
-<ul>
- <li>All primitive types in the Java programming language ({@code int}, {@code long}, {@code
-char}, {@code boolean}, etc.)</li>
- <li>{@link java.lang.String}</li>
- <li>{@link java.lang.CharSequence}</li>
- <li>{@link java.util.List}
- <p>All elements in the {@link java.util.List} must be one of the supported data types in this
-list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
-java.util.List} may optionally be used as a "generic" class (e.g. <code>List&lt;String&gt;</code>).
-The actual concrete class that the other side will receive will always be an {@link
-java.util.ArrayList}, although the method will be generated to use the {@link
-java.util.List} interface.</p>
- </li>
- <li>{@link java.util.Map}
- <p>All elements in the {@link java.util.Map} must be one of the supported data types in this
-list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
-(such as those of the form
-{@code Map&lt;String,Integer&gt;} are not supported. The actual concrete class that the other side
-will receive will always be a {@link java.util.HashMap}, although the method will be generated to
-use the {@link java.util.Map} interface.</p>
- </li>
-</ul>
-
-<p>You must include an {@code import} statement for each additional type not listed above, even if
-they are defined in the same package as your interface.</p>
-
-<p>When defining methods for your service interface, be aware that:</p>
-<ul>
- <li>Methods can take zero or more parameters, and return a value or void.</li>
- <li>All non-primitive parameters require a directional tag indicating which way the data will go.
-Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
- <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
- <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
-needed, because marshalling parameters is expensive.</p></li>
- <li>All code comments included in the {@code .aidl} file are included in the generated {@link
-android.os.IBinder} interface (except for comments before the import and package
-statements).</li>
-</ul>
-
-<p>Here is an example {@code .aidl} file:</p>
-
-<pre>
-// IRemoteService.aidl
-package com.example.android;
-
-// Declare any non-default types here with import statements
-
-/** Example service interface */
-interface IRemoteService {
- /** Request the process ID of this service, to do evil things with it. */
- int getPid();
-
- /** Demonstrates some basic types that you can use as parameters
- * and return values in AIDL.
- */
- void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
- double aDouble, String aString);
-}
-</pre>
-
-<p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
-build your application, the SDK tools will generate the binder class file in your project's
-{@code gen/} directory. The generated file name matches the {@code .aidl} file name, but with a
-{@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
-IRemoteService.java}).</p>
-
-<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
-do not use Eclipse, then the Ant tool generates the binder class next time you build your
-application&mdash;you should build your project with <code>ant debug</code> (or <code>ant
-release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
-link against the generated class.</p>
-
-
-<h3 id="ImplementTheInterface">2. Implement the interface</h3>
-
-<p>When you build your application, the Android SDK tools generate a {@code .java} interface file
-named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
-that is an abstract implementation of its parent interface (for example, {@code
-YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p>
-
-<p class="note"><strong>Note:</strong> {@code Stub} also
-defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
-android.os.IBinder} (usually the one passed to a client's {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
-returns an instance of the stub interface. See the section <a href="#calling">Calling an IPC
-Method</a> for more details on how to make this cast.</p></p>
-
-<p>To implement the interface generated from the {@code .aidl}, extend the generated {@link
-android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods
-inherited from the {@code .aidl} file.</p>
-
-<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
-{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
-
-<pre>
-private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
- public int getPid(){
- return Process.myPid();
- }
- public void basicTypes(int anInt, long aLong, boolean aBoolean,
- float aFloat, double aDouble, String aString) {
- // Does nothing
- }
-};
-</pre>
-
-<p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}),
-which defines the RPC interface for the service. In the next step, this instance is exposed to
-clients so they can interact with the service.</p>
-
-<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
-<ul>
- <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
-about multithreading from the start and properly build your service to be thread-safe.</li>
- <li>By default, RPC calls are synchronous. If you know that the service takes more than a few
-milliseconds to complete a request, you should not call it from the activity's main thread, because
-it might hang the application (Android might display an &quot;Application is Not Responding&quot;
-dialog)&mdash;you should usually call them from a separate thread in the client. </li>
- <li>No exceptions that you throw are sent back to the caller.</li>
- <li>Only methods are supported; you cannot expose static fields in AIDL.</li>
-</ul>
-
-
-<h3 id="ExposeTheInterface">3. Expose the interface to clients</h3>
-
-<p>Once you've implemented the interface for your service, you need to expose it to
-clients so they can bind to it. To expose the interface
-for your service, extend {@link android.app.Service Service} and implement {@link
-android.app.Service#onBind onBind()} to return an instance of your class that implements
-the generated {@code Stub} (as discussed in the previous section). Here's an example
-service that exposes the {@code IRemoteService} example interface to clients. </p>
-
-<pre>
-public class RemoteService extends Service {
- &#64;Override
- public void onCreate() {
- super.onCreate();
- }
-
- &#64;Override
- public IBinder onBind(Intent intent) {
- // Return the interface
- return mBinder;
- }
-
- private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
- public int getPid(){
- return Process.myPid();
- }
- public void basicTypes(int anInt, long aLong, boolean aBoolean,
- float aFloat, double aDouble, String aString) {
- // Does nothing
- }
- };
-}
-</pre>
-
-<p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService
-bindService()} to connect to this service, the client's {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the
-{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()}
-method.</p>
-
-<p>The client must also have access to the interface class, so if the client and service are in
-separate applications, then the client's application must have a copy of the {@code .aidl} file
-in its {@code src/} directory (which generates the {@code android.os.Binder}
-interface&mdash;providing the client access to the AIDL methods).</p>
-
-<p>When the client receives the {@link android.os.IBinder} in the {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
-<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
-parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
-
-<pre>
-IRemoteService mIRemoteService;
-private ServiceConnection mConnection = new ServiceConnection() {
- // Called when the connection with the service is established
- public void onServiceConnected(ComponentName className, IBinder service) {
- // Following the example above for an AIDL interface,
- // this gets an instance of the IRemoteInterface, which we can use to call on the service
- mIRemoteService = IRemoteService.Stub.asInterface(service);
- }
-
- // Called when the connection with the service disconnects unexpectedly
- public void onServiceDisconnected(ComponentName className) {
- Log.e(TAG, "onServiceDisconnected");
- }
-};
-</pre>
-
-<p>For more sample code, see the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
-RemoteService.java}</a> class in <a
-href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
-
-
-
-
-
-
-
-
-<h2 id="PassingObjects">Passing Objects over IPC</h2>
-
-<p>If you have a class that you would like to send from one process to another through
-an IPC interface, you can do that. However, you must ensure that the code for your class is
-available to the other side of the IPC and the class must support the {@link
-android.os.Parcelable} interface, in order for the objects to be decomposed into primitives and
-marshalled across processes by the Android system.</p>
-
-<p>There are five parts to making a class support the {@link android.os.Parcelable} protocol:</b>
-<ol>
-<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
-<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
-current state of the object and writes it to a {@link android.os.Parcel}.</li>
-<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
-the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
-<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
-{@code Rect.aidl} file, below).
- <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
-build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
-</ol>
-
-<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
-your objects.</p>
-
-<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
-parcelable:</p>
-
-<pre>
-package android.graphics;
-
-// Declare Rect so AIDL can find it and knows that it implements
-// the parcelable protocol.
-parcelable Rect;
-</pre>
-
-<p>And here is an example of how the {@link android.graphics.Rect} class implements the
-{@link android.os.Parcelable} protocol.</p>
-
-<pre>
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class Rect implements Parcelable {
- public int left;
- public int top;
- public int right;
- public int bottom;
-
- public static final Parcelable.Creator&lt;Rect&gt; CREATOR = new
-Parcelable.Creator&lt;Rect&gt;() {
- public Rect createFromParcel(Parcel in) {
- return new Rect(in);
- }
-
- public Rect[] newArray(int size) {
- return new Rect[size];
- }
- };
-
- public Rect() {
- }
-
- private Rect(Parcel in) {
- readFromParcel(in);
- }
-
- public void writeToParcel(Parcel out) {
- out.writeInt(left);
- out.writeInt(top);
- out.writeInt(right);
- out.writeInt(bottom);
- }
-
- public void readFromParcel(Parcel in) {
- left = in.readInt();
- top = in.readInt();
- right = in.readInt();
- bottom = in.readInt();
- }
-}
-</pre>
-
-<p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other
-methods on {@link android.os.Parcel} to see the other kinds of values you can write
-to a Parcel.</p>
-
-<p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving
-data from other processes. In this case, the {@code Rect} will read four numbers from the {@link
-android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of
-values for whatever the caller is trying to do. See <a
-href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
-information about how to keep your application secure from malware.</p>
-
diff --git a/docs/html/guide/topics/fundamentals/bound-services.jd b/docs/html/guide/topics/fundamentals/bound-services.jd
index e5d626c..ec7d723 100644
--- a/docs/html/guide/topics/fundamentals/bound-services.jd
+++ b/docs/html/guide/topics/fundamentals/bound-services.jd
@@ -170,7 +170,7 @@ can then extend within your service.</p>
create a bound service, because it may require multithreading capabilities and
can result in a more complicated implementation. As such, AIDL is not suitable for most applications
and this document does not discuss how to use it for your service. If you're certain that you need
-to use AIDL directly, see the <a href="{@docRoot}guide/topics/advanced/aidl.html">AIDL</a>
+to use AIDL directly, see the <a href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a>
document.</p>
@@ -341,7 +341,7 @@ service, which must then handle multi-threading.</p>
<p>For most applications, the service doesn't need to perform multi-threading, so using a {@link
android.os.Messenger} allows the service to handle one call at a time. If it's important
that your service be multi-threaded, then you should use <a
-href="{@docRoot}guide/topics/advanced/aidl.html">AIDL</a> to define your interface.</p>
+href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> to define your interface.</p>
</div>
</div>