展会信息港展会大全

android开发AIDL实例
来源:互联网   发布日期:2016-01-14 12:22:40   浏览:1560次  

导读:由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象。在Android平台,一个进程通常不能访问另一个进程的内存空间。但是android提供了AIDL可以......

由于每个应用程序都运行在自己的进程空间,并且可以从应用程序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;

上面的IMyService.aidl保存以后会在gen的相应目录下启动生成如下代码:

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;

}

因为sub类实现了Binder接口,所以以后会使用这个类。

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();

indexindex = 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

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港