android开发AIDL实例
来源:互联网 发布:网络机顶盒看电视软件 编辑:程序博客网 时间:2024/05/17 23:04
From: http://blog.csdn.net/wangkuifeng0118/article/details/7277680
由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象。在Android平台,一个进程通常不能访问另一个进程的内存空间。但是android提供了AIDL可以用来进程间数据传递。
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
下面通过一个实例来演示AIDL,因为是进程之间数据传递,所以这里要使用建立android工程,一个是AIDL的服务端另一个是客户端.
服务端的实现步骤:
1.创建.aidl文件 IMyService.aidl
- package cn.com.karl.aidl;
- import cn.com.karl.aidl.Person;
- interface IMyService {
- void savePersonInfo(in Person person);
- List<Person> getAllPerson();
- String sayHello();
- }
因为这里用到了Peson对象,所以要创建一个person类。Person类,是一个序列化的类,这里使用Parcelable 接口来序列化,是Android提供的一个比Serializable 效率更高的序列化类。
- public class Person implements Parcelable {
- private String name;
- private String telNumber;
- private int age;
- public Person() {}
- public Person(Parcel pl){
- name = pl.readString();
- telNumber = pl.readString();
- age = pl.readInt();
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getTelNumber() {
- return telNumber;
- }
- public void setTelNumber(String telNumber) {
- this.telNumber = telNumber;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public int describeContents() {
- return 0;
- }
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeString(telNumber);
- dest.writeInt(age);
- }
- public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
- @Override
- public Person createFromParcel(Parcel source) {
- return new Person(source);
- }
- @Override
- public Person[] newArray(int size) {
- return new Person[size];
- }
- };
- }
然后创建Person.aidl文件,注意这里的parcelable小写。
- package cn.com.karl.aidl;
- parcelable Person;
Binder
- package cn.com.karl.aidl;
- public interface IMyService extends android.os.IInterface
- {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends android.os.Binder implements cn.com.karl.aidl.IMyService
- {
- private static final java.lang.String DESCRIPTOR = "cn.com.karl.aidl.IMyService";
- /** Construct the stub at attach it to the interface. */
- public Stub()
- {
- this.attachInterface(this, DESCRIPTOR);
- }
- /**
- * Cast an IBinder object into an cn.com.karl.aidl.IMyService interface,
- * generating a proxy if needed.
- */
- public static cn.com.karl.aidl.IMyService 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 cn.com.karl.aidl.IMyService))) {
- return ((cn.com.karl.aidl.IMyService)iin);
- }
- return new cn.com.karl.aidl.IMyService.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_savePersonInfo:
- {
- data.enforceInterface(DESCRIPTOR);
- cn.com.karl.aidl.Person _arg0;
- if ((0!=data.readInt())) {
- _arg0 = cn.com.karl.aidl.Person.CREATOR.createFromParcel(data);
- }
- else {
- _arg0 = null;
- }
- this.savePersonInfo(_arg0);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_getAllPerson:
- {
- data.enforceInterface(DESCRIPTOR);
- java.util.List<cn.com.karl.aidl.Person> _result = this.getAllPerson();
- reply.writeNoException();
- reply.writeTypedList(_result);
- return true;
- }
- case TRANSACTION_sayHello:
- {
- data.enforceInterface(DESCRIPTOR);
- java.lang.String _result = this.sayHello();
- reply.writeNoException();
- reply.writeString(_result);
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- private static class Proxy implements cn.com.karl.aidl.IMyService
- {
- 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 savePersonInfo(cn.com.karl.aidl.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_savePersonInfo, _data, _reply, 0);
- _reply.readException();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- public java.util.List<cn.com.karl.aidl.Person> getAllPerson() throws android.os.RemoteException
- {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- java.util.List<cn.com.karl.aidl.Person> _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getAllPerson, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createTypedArrayList(cn.com.karl.aidl.Person.CREATOR);
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
- public java.lang.String sayHello() throws android.os.RemoteException
- {
- android.os.Parcel _data = android.os.Parcel.obtain();
- android.os.Parcel _reply = android.os.Parcel.obtain();
- java.lang.String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- }
- finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
- }
- static final int TRANSACTION_savePersonInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
- static final int TRANSACTION_getAllPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
- static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
- }
- public void savePersonInfo(cn.com.karl.aidl.Person person) throws android.os.RemoteException;
- public java.util.List<cn.com.karl.aidl.Person> getAllPerson() throws android.os.RemoteException;
- public java.lang.String sayHello() throws android.os.RemoteException;
- }
2.实现service类
- public class RemoteService extends Service {
- private LinkedList<Person> personList = new LinkedList<Person>();
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
- private final IMyService.Stub mBinder = new IMyService.Stub(){
- @Override
- public void savePersonInfo(Person person) throws RemoteException {
- if (person != null){
- personList.add(person);
- }
- }
- @Override
- public List<Person> getAllPerson() throws RemoteException {
- return personList;
- }
- @Override
- public String sayHello() throws RemoteException {
- // TODO Auto-generated method stub
- return "欢迎你通过AIDL访问服务器端";
- }
- };
- }
3.客户端实现步骤:
首先建立一个项目,把服务端的
包和类一起拷贝到客户端项目中。因为客户端要和服务端通信,必须要使用同一个aidl。
然后构造客户端的activity类:
- public class RemoteClientActivity extends Activity {
- /** Called when the activity is first created. */
- private TextView textHello,textPerson;
- private IMyService myService;
- private Button btnSave;
- private Button btnGet;
- private static Boolean mIsRemoteBound=false;
- private ServiceConnection conn=new ServiceConnection() {
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // TODO Auto-generated method stub
- myService=null;
- }
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- // TODO Auto-generated method stub
- myService=IMyService.Stub.asInterface(service);
- try {
- textHello.setText(myService.sayHello());
- } catch (RemoteException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- textHello=(TextView) this.findViewById(R.id.textHello);
- btnSave=(Button) this.findViewById(R.id.btnSave);
- btnGet=(Button) this.findViewById(R.id.btnGet);
- textPerson=(TextView) this.findViewById(R.id.textPerson);
- if(mIsRemoteBound){
- unbindService(conn);
- }else{
- Intent intent=new Intent("cn.com.karl.aidl.RemoteService");
- bindService(intent, conn, BIND_AUTO_CREATE);
- }
- mIsRemoteBound = !mIsRemoteBound;
- btnSave.setOnClickListener(new OnClickListener() {
- private int index = 0;
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Person person = new Person();
- index = index + 1;
- person.setName("Person" + index);
- person.setAge(20);
- person.setTelNumber("123456");
- try {
- myService.savePersonInfo(person);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- });
- btnGet.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- List<Person> list = null;
- try {
- list = myService.getAllPerson();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- if (list != null){
- StringBuilder text = new StringBuilder();
- for(Person person : list){
- text.append("\n联系人:");
- text.append(person.getName());
- text.append("\n 年龄:");
- text.append(person.getAge());
- text.append("\n 电话:");
- text.append(person.getTelNumber());
- }
- textPerson.setText(text);
- }else {
- Toast.makeText(RemoteClientActivity.this, "得到数据出错",
- Toast.LENGTH_SHORT).show();
- }
- }
- });
- }
- }
最后不要忘记注册service:
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity android:name=".MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service android:name=".RemoteService">
- <intent-filter >
- <action android:name="cn.com.karl.aidl.RemoteService"></action>
- </intent-filter>
- </service>
- </application>
启动service的时候使用了隐士意图。
运行服务端工程.
服务端已经启动,然后运行客户端工程:
OK,已经从服务端得到了数据,第一句话就是从服务端得到的,下面看看,传递对象和获取对象与服务端。
点击添加联系人,然后点击获取联系人按钮:
- android开发AIDL实例
- android开发AIDL实例
- android开发AIDL实例
- Android开发基础之AIDL教程实例
- AIDL开发实例
- Android Aidl简单实例
- Android AIDL使用实例
- android aidl 使用实例
- android aidl实例
- Android AIDL实例解析
- Android AIDL实例解析
- Android Aidl简单实例
- android aidl 使用实例
- Android AIDL实例
- Android开发指南-AIDL
- Android AIDL开发
- Android开发之---AIDL
- AIDL使用实例(android)
- d第十六周上机项目2 用指针玩字符串
- spring iBATIS 整合
- VS2010基于DirectShows实现视频预览控件
- Android学习之生命周期
- 【HEVC学习与研究】12.HEVC的高层语法结构
- android开发AIDL实例
- NEERC2013 Kabaleo Lite
- 【HEVC学习与研究】13.NAL unit解码
- Linux系统各种监控命令
- android 利用WakeLock延迟系统深度睡眠
- Android Notificaton
- python获得线程调用函数的返回值
- 《Java虚拟机规范》阅读(二):编译
- poj 3592 Instantaneous Transference 强连通缩点+在DAG上dp求最长路