Android Service总结06 之AIDL
Android Service总结06 之AIDL
版本 |
版本说明 |
发布时间 |
发布人 |
V1.0 |
初始版本 |
2013-04-03 |
Skywang |
1 AIDL介绍
AIDL,即Android InterfaceDefinition Language。
Android使用AIDL来完成进程间通信(IPC),并且一般在服务需要接受不同应用多线程的请求时才需要使用AIDL;如果是同一个应用内的请求使用Binder实现即可;如果只是应用间通信而不是多线程处理的话使用Messenger,当然这两种情况也可以使用AIDL。本地进程和远程进程使用AIDL有所不同,本地进程内调用时会都在调用的线程内执行,远程进程使用是通过Service进程内一个由系统维护的线程池发出调用,所以可能是未知线程同时调用,需要注意线程安全问题。
2 AIDL示例
创建AIDL服务的步骤:
(01)创建.aidl文件。 .aidl是接口文件,它定义了服务所能提供的功能。
(02)实现.aidl所定义的接口。
(03)将接口开放给其它应用程序。
2.1 创建.aidl文件
(01)打开eclipse,新建工程”AIDLServiceImpl”,然后在工程的“com.text”包下创建“MyAIDLInterface.aidl”文件。
如下图:
(02)编辑“MyAIDLInterface.aidl”,提供doubleValue(int val)和halfValue(int value)服务。
“MyAIDLInterface.aidl”代码如下:
package com.test; interface MyAIDLInterface { void doubleValue(int val); void halfValue(int val);
}
(03)编译工程,在“gen”目录下会自动生成与“MyAIDLInterface.aidl”对应的“MyAIDLInterface.java”文件。
如下图:
“MyAIDLInterface.java”代码如下:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: F:\\workout\\android\\AIDLServiceImpl\\src\\com\\test\\MyAIDLInterface.aidl
*/
package com.test;
public interface MyAIDLInterface extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.test.MyAIDLInterface
{
private static final java.lang.String DESCRIPTOR = "com.test.MyAIDLInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.test.MyAIDLInterface interface,
* generating a proxy if needed.
*/
public static com.test.MyAIDLInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.test.MyAIDLInterface))) {
return ((com.test.MyAIDLInterface)iin);
}
return new com.test.MyAIDLInterface.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_doubleValue:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
this.doubleValue(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_halfValue:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
this.halfValue(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.test.MyAIDLInterface
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public void doubleValue(int val) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_doubleValue, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
public void halfValue(int val) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_halfValue, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_doubleValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_halfValue = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void doubleValue(int val) throws android.os.RemoteException;
public void halfValue(int val) throws android.os.RemoteException;
}
2.2 实现.aidl所定义的接口
(04)在“com.test”包下新建文件MyAIDLService.java,并实现doubleValue(int val)和halfValue(int value)接口。
如下图:
MyAIDLService.java的代码如下:
package com.test; import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log; public class MyAIDLService extends Service{
private static final String TAG = "skywang-->MyAIDLService"; private MyAIDLInterface.Stub myBinder =
new MyAIDLInterface.Stub() { @Override
public void halfValue(int val) throws RemoteException {
Log.d(TAG, "halfValue val="+val/2); } @Override
public void doubleValue(int val) throws RemoteException {
Log.d(TAG, "doubleValue val="+val*2);
}
};
@Override
public void onCreate() {
super.onCreate();
} @Override
public void onDestroy(){
super.onDestroy();
} @Override
public IBinder onBind(Intent intent) {
return myBinder;
}
}
(05) 定义aidl对应的manifest
manifest内容如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="17" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" > <service android:name=".MyAIDLService" android:process=":remote">
<intent-filter>
<action android:name="com.test.MY_AIDL_SERVICE" />
</intent-filter>
</service> </application> </manifest>
至此,我们已经完成了.aidl服务的定义和实现。
2.3 将接口开放给其它应用程序
(06)新建一个工程“AIDLServiceTest”,然后在工程的“com.skywang”包下创建AIDLServiceTest.java;
(07)然后,将MyAIDLInterface.aidl文件拷贝到AIDLServiceTest工程的“com.test”包下。
如下图:
注意:.aidl所在的包名,必须和定义它的包名一样!(即MyAIDLInterface.aidl所在的定义它的工程的包为com.test;那么,调用MyAIDLInterface.aidl的程序,也必须把MyAIDLInterface.aidl放在com.test包下面)
(08)AIDLServiceTest.java首先必须实现ServiceConnection接口。
实现ServiceConnection接口的原因是:我们在后面调用.aidl服务的时候,必须通过bindService()去绑定服务;而bindService()需要用到ServiceConnection对象。
实现ServiceConnection很简单,只需要实现两个接口:
onServiceConnected —— 连上服务的回调函数。一般在此函数中,获取服务对象。
onServiceDisconnected —— 断开服务的回调函数。可以直接返回null。
ServiceConnection的实现代码如下:
private MyAIDLInterface mBinder = null;
private ServiceConnection mConnection = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
mBinder = null;
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "Service connected!");
mBinder = MyAIDLInterface.Stub.asInterface(service);
}
};
(09)开始访问服务之前,我们要先通过bindService()绑定服务;使用完毕之后,通过unbindService()断开服务。
AIDLServiceTest.java代码如下:
package com.skywang; import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.content.ComponentName;
import android.content.Intent;
import android.content.Context;
import android.content.ServiceConnection;
import com.test.MyAIDLInterface; public class AIDLServiceTest extends Activity {
private static final String TAG = "skywang-->AIDLServiceTest"; private Button mStart = null;
private Button mHalf = null;
private Button mDouble = null;
private Button mEnd = null; private MyAIDLInterface mBinder = null;
private ServiceConnection mConnection = new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
mBinder = null;
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "Service connected!");
mBinder = MyAIDLInterface.Stub.asInterface(service);
}
}; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aidlservice_test); mStart = (Button) findViewById(R.id.btStart);
mStart.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View arg0) {
Log.d(TAG, "click start button"); Intent intent = new Intent("com.test.MY_AIDL_SERVICE");
boolean result = bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
if (!result) {
mBinder = null;
}
}
}); mHalf = (Button) findViewById(R.id.btHalf);
mHalf.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View arg0) {
Log.d(TAG, "click half button"); try {
if (mBinder != null) {
mBinder.halfValue(10);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}); mDouble = (Button) findViewById(R.id.btDouble);
mDouble.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View arg0) {
Log.d(TAG, "click double button"); try {
if (mBinder != null) {
mBinder.doubleValue(10);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}); mEnd = (Button) findViewById(R.id.btEnd);
mEnd.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View arg0) {
Log.d(TAG, "click end button"); if (mBinder != null) {
unbindService(mConnection);
mBinder = null;
}
}
});
} }
3 示例演示
程序运行效果图:
点击“Start”按钮,Logcat如下:
DEBUG/skywang-->AIDLServiceTest(276):click half button
DEBUG/skywang-->AIDLServiceTest(276):Service connected!
点击“Half”按钮,Logcat如下:
DEBUG/skywang-->AIDLServiceTest(276):click half button
DEBUG/skywang-->MyAIDLService(285):halfValue val=5
点击“Double”按钮,Logcat如下:
DEBUG/skywang-->AIDLServiceTest(276):click double button
DEBUG/skywang-->MyAIDLService(285):doubleValue val=20
点击“End”按钮,Logcat如下:
DEBUG/skywang-->AIDLServiceTest(276):click end button
4 参考文献
1. Android API文档:http://developer.android.com/guide/components/aidl.html
2. Android AIDL使用详解:http://blog.csdn.net/stonecao/article/details/6425019
点击下载:源代码
更多service内容:
2 Android Service总结02 service介绍
3 Android Service总结03 之被启动的服务 -- Started Service
4 Android Service总结04 之被绑定的服务 -- Bound Service
5 Android Service总结05 之IntentService
Android Service总结06 之AIDL的更多相关文章
- Android Service和Binder、AIDL
1.首先理解service的作用和生命周期 由于activity如果切换,那么他就不再运行,那么我们想在玩游戏的时候听播放器中的音乐,activity就应运而生了,这是最常见的一种场景,同时servi ...
- Android Service总结05 之IntentService
Android Service总结05 之IntentService 版本 版本说明 发布时间 发布人 V1.0 添加了IntentService的介绍和示例 2013-03-17 Skywang ...
- Android Service总结04 之被绑定的服务 -- Bound Service
Android Service总结04 之被绑定的服务 -- Bound Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Skywa ...
- Android Service总结01 目录
Android Service总结01 目录 1 Android Service总结01 目录 2 Android Service总结02 service介绍 介绍了“4种service 以及 它们的 ...
- Android Service总结02 service介绍
Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...
- Android Service总结03 之被启动的服务 -- Started Service
Android Service总结03 之被启动的服务 -- Started Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Sky ...
- android service 的各种用法(IPC、AIDL)
http://my.oschina.net/mopidick/blog/132325 最近在学android service,感觉终于把service的各种使用场景和用到的技术整理得比较明白了,受益颇 ...
- Android service binder aidl 关系
/********************************************************************************** * Android servic ...
- Android Service AIDL 远程调用服务 【简单音乐播放实例】
Android Service是分为两种: 本地服务(Local Service): 同一个apk内被调用 远程服务(Remote Service):被另一个apk调用 远程服务需要借助AIDL来完成 ...
随机推荐
- K8S 创建rc 时 不适用本地镜像的解决办法
spec: containers: - name: nginx image: image: reg.docker.lc/share/nginx:latest imagePullPolicy: IfNo ...
- windows无法安装到这个磁盘 gpt分区形式
利用U盘装系统的步骤 工具: Rufus 下载地址:http://rufus.akeo.ie/?locale=zh_CN -------------------------------------- ...
- KUR-Couriers
题目链接: QwQ Solution: 以权值为下标,对每个点建树 对于x点,以它为根的树涵盖的是1到x区间内每个数出现的次数 Code: #include<bits/stdc++.h> ...
- 【转】如何在您的PCB大作上添加二维码?
开篇先给大家来段新闻截选: “8月20日,新加坡总理李显龙在国庆群众大会上演讲时,称中国移动支付(电子支付)领先全球,新加坡的移动支付还很落后,上海路边摊都有移动支付,新加坡人去上海就像乡巴佬. 这番 ...
- 详解掩膜mask
什么是掩膜(mask) 数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中,许多芯片工艺步骤采用光刻技术,用于这些步骤的图形“底片”称为掩膜(也称作“掩模”),其作用是:在硅片上选定的 ...
- debian8.4 系统莫名没有声音
[http://www.linuxdiyf.com/viewarticle.php?id=437020 Debian8, 桌面环境是xfce4, 安装完成后发现前面板音频输出插孔正常,后面板的没声音. ...
- 转:IOS 基于APNS消息推送原理与实现(JAVA后台)
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple ...
- 工具类 | window批处理杀死指定端口进程
window批处理杀死指定端口进程,注意保存时使用ansi格式,运行输入端口即可 @echo off setlocal enabledelayedexpansion set /p port=请输入端口 ...
- python学习笔记5--json处理
import json #json串就是字符串. d = { 'car':{'color':'red','price':100,'count':50}, 'bus':{'color':'red','p ...
- gcc初步窥探
由于没有上过Linux编程这门课,所以Linux学得很水啊!!用来用去都是ls -al ; cd .. ;这些渣命令,尤其gcc都不知道什么东西来的,所以先学一下吧. 一.程序的编译过程 对于GUN编 ...