Merge "docs: move new AIDL doc back into the existing doc, but move the side nav location out of tools" into honeycomb
This commit is contained in:
@@ -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>
|
||||
</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>The code to do that marshalling is tedious to write, so we provide the AIDL tool to do it
|
||||
for you.</p>
|
||||
|
||||
<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="implementing">Implementing IPC Using AIDL</h2>
|
||||
<p>Follow these steps to implement an IPC service using AIDL.</p>
|
||||
<h2>See also</h2>
|
||||
<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="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a></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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
<ul>
|
||||
<li>Primitive Java programming language types (int, boolean, etc)
|
||||
— 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<String>).
|
||||
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<String,Integer>
|
||||
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>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>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;
|
||||
<h2 id="Defining">Defining an AIDL Interface</h2>
|
||||
|
||||
// Declare the interface.
|
||||
interface IBankAccountService {
|
||||
|
||||
// Methods can take 0 or more parameters, and
|
||||
// return a value or void.
|
||||
int getAccountBalance();
|
||||
void setOwnerNames(in List<String> names);
|
||||
|
||||
// Methods can even take other AIDL-defined parameters.
|
||||
BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);
|
||||
<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>
|
||||
|
||||
// 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>
|
||||
<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>
|
||||
|
||||
<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>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="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>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<String></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<String,Integer>} 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>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—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 "Application
|
||||
is Not Responding" 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 "Application is Not Responding"
|
||||
dialog)—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 "publishing your service." 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 {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
}
|
||||
|
||||
@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—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>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
<h3 id="parcelable">Pass by value Parameters using Parcelables</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<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<Rect> CREATOR = new Parcelable.Creator<Rect>() {
|
||||
public static final Parcelable.Creator<Rect> CREATOR = new
|
||||
Parcelable.Creator<Rect>() {
|
||||
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>
|
||||
|
||||
<pre class="prettyprint">
|
||||
package android.graphics;
|
||||
|
||||
// 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
|
||||
<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"><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>
|
||||
<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>
|
||||
|
||||
<h2 id="calling">Calling an IPC Method</h2>
|
||||
<p>Here are the steps a calling class should make to call your remote interface: </p>
|
||||
|
||||
|
||||
<h2 id="Calling">Calling an IPC Method</h2>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -755,6 +754,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>
|
||||
|
||||
@@ -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—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<String></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<String,Integer>} 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—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 "Application is Not Responding"
|
||||
dialog)—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 {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
}
|
||||
|
||||
@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—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<Rect> CREATOR = new
|
||||
Parcelable.Creator<Rect>() {
|
||||
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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user