- 浏览: 77299 次
- 性别:
- 来自: 上海
最新评论
-
dodomelee:
Android 广播机制 -
追逐779:
是不是发错了,工程呢?谢谢
Android 广播机制 -
aaa12:
怎么是个apk 呀?
Android 广播机制
跨进程访问(AIDL服务)
Android系统中的进程之间不能共 享内存,因此,需要提供一些机制在不同进程之间进行数据通信。在4个Android应用程序组件中的3个(Activity、Broadcast和 Content Provider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以,也即AIDL服务。
什么是AIDL服务
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure
Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition
Language,IDL)来公开服务的接口。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface
Definition Language)服务。
AIDL (Android Interface Definition Language)是一种IDL
语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中
(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
使用AIDL实现IPC(Implementing IPC Using AIDL):
1. 创建.aidl文件-该文件(YourInterface.aidl)定义了客户端可用的方法和数据的接口。
2. 在makefile文件中加入.aidl文件-(Eclipse中的ADT插件提供管理功能)Android包括名为AIDL的编译器,位于tools/文件夹。
3. 实现接口-AIDL编译器从AIDL接口文件中利用Java语言创建接口,该接口有一个继承的命名为Stub的内部抽象类(并且实现了一些IPC调用的附加方法),要做的就是创建一个继承于YourInterface.Stub的类并且实现在.aidl文件中声明的方法。
4. 向客户端公开接口-如果是编写服务,应该继承Service并且重载Service.onBind(Intent) 以返回实现了接口的对象实例
在创建YourInterface.aidl文件时,需要注意: AIDL 服务只支持有限的数据类型,即Java基本类型、集合类型、AIDL 自动生成的接口(需要手动import),如果需要使用复杂的数据就需要做更一步处理,比如实现了android.os.Parcelable 接口的类(需要import),而且要注意为实现了Parcelable 接口的类创建一个对应的aidl文件,文件名和类名相同,文件内容为:除了package必须有parcelable YourInterface。
一个简单的AIDL设计
创建AIDL文件,在这个aidl中使用的复杂的数据类型(Person,Male,Female都实现了接口android.os.Parcelable):
package com.aidl.service; import com.aidl.service.Person; import com.aidl.service.Male; import com.aidl.service.Female; interface IPersonService { Female getFemale(String name); Male getMale(String name); Person getPerson(String name); List<Person> getPersons(); List<Female> getFemales(); List<Male> getMales(); void createPerson(in Person person); void createFemale(in String name, in String telNumber, in int age); void createMale(in String name, in String telNumber, in int age); int getFemaleCount(); int getMaleCount(); int getPersonCount(); }
Person.aild(Male,Female类似)很简单:
package com.aidl.service; parcelable Person;
此时可以编译项目,Eclipse会在gen下自动生成IPersonService.java,该类中自动生成了Stub抽象类以及asInterface()等:
package com.aidl.service; public interface IPersonService extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.aidl.service.IPersonService { private static final java.lang.String DESCRIPTOR = "com.aidl.service.IPersonService"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.aidl.service.IPersonService interface, * generating a proxy if needed. */ public static com.aidl.service.IPersonService 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.aidl.service.IPersonService))) { return ((com.aidl.service.IPersonService)iin); } return new com.aidl.service.IPersonService.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } /** * 省略...... */ public void createPerson(com.aidl.service.Person person) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((person!=null)) { _data.writeInt(1); person.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_createPerson, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } public void createFemale(java.lang.String name, java.lang.String telNumber, int age) 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.writeString(name); _data.writeString(telNumber); _data.writeInt(age); mRemote.transact(Stub.TRANSACTION_createFemale, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } public com.aidl.service.Female getFemale(java.lang.String name) throws android.os.RemoteException; public com.aidl.service.Male getMale(java.lang.String name) throws android.os.RemoteException; public com.aidl.service.Person getPerson(java.lang.String name) throws android.os.RemoteException; public java.util.List<com.aidl.service.Person> getPersons() throws android.os.RemoteException; public java.util.List<com.aidl.service.Female> getFemales() throws android.os.RemoteException; public java.util.List<com.aidl.service.Male> getMales() throws android.os.RemoteException; public void createPerson(com.aidl.service.Person person) throws android.os.RemoteException; public void createFemale(java.lang.String name, java.lang.String telNumber, int age) throws android.os.RemoteException; public void createMale(java.lang.String name, java.lang.String telNumber, int age) throws android.os.RemoteException; public int getFemaleCount() throws android.os.RemoteException; public int getMaleCount() throws android.os.RemoteException; public int getPersonCount() throws android.os.RemoteException; }
配置Manifest.xml文件,下面是一个最最简单的配置方式:
<service android:name="com.aidl.service.PersonService"> <intent-filter> <action android:name="com.aidl.service.action.PersonService" /> </intent-filter> </service>
实现Service,类名可以根据自己喜好来定,Service中最主要的是实现aidl中各个方法,即,Stub中没有实现的抽象方法这里需要注意onBind()返回Stub:
package com.aidl.service; import com.aidl.service.Person.SEX; public class PersonService extends Service { private final String TAG = "PersonService"; @Override public void onCreate() { super.onCreate(); males = new ArrayList<Male>(); females = new ArrayList<Female>(); mPerson = new ArrayList<Person>(); } @Override public void onDestroy() { super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public IBinder onBind(Intent intent) { return mPersonBinder; } private List<Male> males; private List<Female> females; private List<Person> mPerson; private IPersonService.Stub mPersonBinder = new IPersonService.Stub() { @Override public Female getFemale(String name) throws RemoteException { Female result = null; if (females == null || name == null || name.length() == 0) return null; for (Female f : females) { if (f.getName() != null && f.getName().length() > 0 && f.getName().equals(name)) { result = f; break; } } return result; } /** * * 此处省略其余方法的实现 * */ }
接下来可以定义自己外部使用的ServiceConnection,主要是onServiceConnected()构造你的接口类型,onServiceDisconnected()断开服务时处理,通常我们的ServiceConnection是一个单例,实现了Service的连接(connect)/断开(unconnect)方法:
package com.aidl.service; public class PersonServiceConnent implements ServiceConnection { private static final String TAG = "PersonServiceConnent"; private Context mContext; private static PersonServiceConnent connect; private final static Object synObj = new Object(); private IPersonService myInterface; public static final String SERVICE_ACTION = "com.aidl.service.action.PersonService"; public static final String SERVICE_PACKAGENAME = "com.aidl.main"; public static final String SERVICE_CLASSNAME = "com.aidl.service.PersonService"; @Override public void onServiceConnected(ComponentName name, IBinder service) { myInterface = IPersonService.Stub.asInterface(service); if (myInterface == null) Log.i(TAG, "in onServiceConnected() getCurrentPosition == null"); else Log.i(TAG, "in onServiceConnected() getCurrentPosition != null"); } @Override public void onServiceDisconnected(ComponentName name) { myInterface = null; bConnected = false; Log.i(TAG, "onServiceDisconnected:" + name); } private PersonServiceConnent(Context context) { mContext = context; } public static PersonServiceConnent Instance(Context context) { if (connect == null) { synchronized (synObj) { if (connect == null) connect = new PersonServiceConnent(context); } } return connect; } private Intent mIntent = new Intent(); private boolean bStartService = false; private boolean bConnected = false; private ComponentName mComponentName; public synchronized boolean connect(Context context) { if (context == null) return false; mContext = context; mIntent.setAction(SERVICE_ACTION); if (!bStartService) { mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { mComponentName = mContext.startService(mIntent); if (mComponentName != null) { bStartService = true; } } catch (Exception e) { e.printStackTrace(); } } if (connect != null && !connect.bConnected) { connect.bConnected = mContext.bindService(mIntent, connect, Context.BIND_AUTO_CREATE); if (!connect.bConnected) { try { mContext.unbindService(connect); } catch (Exception e) { } try { mContext.startActivity(mIntent); } catch (Exception e) { } try { connect.bConnected = mContext.bindService(mIntent, connect, Context.BIND_AUTO_CREATE); } catch (Exception e) { } } } return connect.bConnected; } public void unconnect() { if (mContext == null) return; else unconnect(mContext); } public void unconnect(Context context) { if (context == null) context = mContext; if (context == null) return; if (connect != null) { if (connect.bConnected) { try { context.unbindService(connect); bConnected = false; } catch (Exception e) { } try { Intent tmpIntent = new Intent(); if (mComponentName != null) { tmpIntent.setComponent(mComponentName); } else { tmpIntent.setClassName(SERVICE_PACKAGENAME, SERVICE_CLASSNAME); } context.stopService(tmpIntent); bStartService = false; } catch (Exception e) { Log.e(TAG, "unconnect error", e); } } } } /** * getFemale()供我们在外部调用ServiceConnection的时候使用,其实现就是调用Service中的方法而已 * @param name * @return */ public Female getFemale(String name) { if (myInterface == null) { Log.i(TAG, "in getFemale() myInterface == null"); this.connect(mContext); return null; } try { return myInterface.getFemale(name); } catch (RemoteException e) { Log.i(TAG, "getFemale()", e); return null; } } /** * * 省略其余类似getFemale方法的实现 * */ }
在上面的ServiceConnection的代码中,onServiceConnected获取Service使用了Stub.asInterface(service),这种方式是常见的。其中的connect和unconnect也是比较常见的写法,基本类似。connect中,Intent的Action必须与AndroidManifest.xml中对应<service>的action一致。在unconnect中setClassName(String packageName, String className)的参数需要注意packageName为应用的packageName,而非简单的class的package,className为绝对class(带包名)。
这样就比较完整的实现了一个AIDL,这里的例子虽然比较简单,但是AIDL实现的过程和步骤基本是一样的,而对于ServiceConnection中最主要的几个方法的写法也基本大同小异。
发表评论
-
Android 广播机制
2011-11-21 17:48 3237一听广播二字,我们第一感觉就会联想到了小时候村里的广播 ... -
Android中的Parcel机制 实现Bundle传递对象
2011-11-18 17:27 19151Android中的Parcel机制 实现了Bundl ... -
Android开发中用到的命令
2011-08-19 22:16 701Android开发中用到的命令 一些命令,不常用就忘记了,特 ... -
Android基本组件
2011-08-19 22:14 930[转]Android基本组件 B ... -
Android下基于XML的Graphics shape使用方法
2011-08-19 22:09 2128<shape xmlns:android="h ... -
Android activity属性设置大全
2011-08-19 21:58 884activity属性设置大全 android:allowTa ... -
android 消息提醒(Toast,Notification)
2011-08-19 21:55 1488android 提醒(Toast,Notification) ... -
Android AlertDialog去除白色边框
2011-08-12 13:33 1559使用styles.xml风格: <style ... -
Android Spannable设置TextView样式
2011-08-10 13:30 1815Spannable span = (Spannable) ... -
Android 音频录音
2011-07-19 14:40 1134检查SDcard是否存在: private boole ... -
Android图片圆角处理
2011-06-27 17:16 1711public static Bitmap getRoun ...
相关推荐
AIDL是一种接口定义语言,类似于Java中的接口,但它专门用于定义跨进程通信的接口。通过AIDL,开发者可以创建一个接口,该接口在服务(Service)端定义,客户端(Client)可以通过这个接口与服务进行通信。AIDL文件...
Aidl是一种接口定义语言,用于描述服务端公开的接口和方法。通过Aidl,客户端可以透明地调用服务端的方法,就像调用本地对象一样。Aidl编译后会生成Java代码,实现跨进程调用所需的代理类和服务端的Stub类。 **3. ...
Android AIDL(Android Interface Definition Language)是一种基于接口定义语言,用于定义 Android 应用程序之间的接口。AIDL 文件是用于定义服务端和客户端之间的接口,用于实现远程过程调用(RPC)。但是, 当...
AIDL(Android Interface Definition Language)是Android提供的一种接口定义语言,用于支持跨进程调用方法,从而实现多进程间的通信。 AIDL的基本原理是将接口定义为一个.aidl文件,系统会自动生成对应的Java代码...
而AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于处理进程间通信(IPC, Inter-Process Communication)。当需要在第三方应用中与WPS Office进行交互时,AIDL就成为了一个...
1. **AIDL简介**:AIDL是Android提供的接口定义语言,用于处理Android应用间的跨进程通信(IPC, Inter-Process Communication)。通过AIDL,应用可以暴露一部分功能给其他应用调用,就像Java中的接口一样。 2. **...
AIDL是一种接口定义语言,它允许你在Android应用之间定义接口,以实现进程间的通信(IPC)。当你在服务中定义一个AIDL接口,并在客户端调用这个接口时,系统会自动生成相应的 Binder 类,以处理跨进程的调用。 接...
- AIDL是一种接口定义语言,它的主要作用是让不同的Android进程能够安全、高效地进行通信。 - 当一个服务需要在多个进程中暴露其接口时,就需要用到AIDL。 2. **AIDL文件结构** - AIDL文件通常以`.aidl`为扩展名...
Android AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于处理进程间通信(IPC, Inter-Process Communication)。在Android应用开发中,当需要在不同进程间共享数据或者...
aidl是一种接口定义语言,类似于Java中的接口,它允许开发者定义可以在不同进程中传递的数据类型和方法。当我们编写一个.aidl文件时,Android编译器会自动生成对应的Java接口和Stub类,这些类实现了跨进程通信的必要...
Android AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于实现不同应用程序进程间的通信(IPC,Inter-Process Communication)。AIDL允许我们定义服务和服务客户端之间交互...
它是Android系统提供的一种接口定义语言,类似于Java中的接口,但它的目的是让不同进程间的组件能够相互通信。当一个应用需要与另一个应用进行数据交换时,AIDL就派上了用场。在这个Demo中,我们将看到如何创建一个...
1. **序列化**:将Bitmap转换为字节数组或Base64字符串,然后在AIDL接口中传递。这样可以减小内存压力,但增加了网络传输的负担。 2. **使用文件共享**:将Bitmap保存到外部存储,通过文件URI在服务和Activity之间...
在Android系统中,AIDL(Android Interface Definition Language)是一种接口定义语言,用于处理跨进程通信(IPC, Inter-Process Communication)。远程服务(Remote Service)是Android应用组件之一,它允许其他...
AIDL本质上是Android系统提供的一种接口定义语言,它允许开发者定义接口,这些接口可以在不同的Android进程间调用。当你在服务端定义了一个AIDL接口后,Android编译器会自动生成相应的Java代码,这些代码实现了进程...
在Android系统中,AIDL(Android Interface Definition Language)是一种接口定义语言,用于处理进程间通信(IPC, Inter-Process Communication)。当一个应用需要与另一个应用的组件进行交互,特别是跨越不同进程时...
AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于在不同进程间进行通信,特别是当服务(Service)需要与客户端(如Activity)跨进程交互时。AIDL帮助开发者定义接口,使得...
而Android Interface Definition Language(AIDL)是Google提供的一种用于处理进程间通信的语言,它允许应用程序之间透明地交换数据。当我们需要在不同的应用之间传递复杂的对象时,AIDL就显得尤为重要。本文将深入...
在Android系统中,AIDL(Android Interface Definition Language)是一种接口定义语言,用于实现不同进程间的通信,即远程进程通讯。AIDL使得服务(Service)和活动(Activity)这两个独立的APK之间能够相互通信,...