Android AIDL 实现过程

Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

Aidl文件所在的包名和文件名要相同:

应为用到了parcelable接口,这里先说说它:

Parcelable接口

Android中实现序列化有两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。实现Serializable接口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。

注:Android中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口。

HarlaInfo.Java:

package com.harlan.demo.aidl;

import android.os.Parcel;

import android.os.Parcelable;

public class HarlanInfo implements Parcelable {

private String name;

private int age;

private String place;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getPlace() {

return place;

}

public void setPlace(String place) {

this.place = place;

}

public HarlanInfo() {

}

public HarlanInfo(Parcel parcel) {

this.name = parcel.readString();

this.age = parcel.readInt();

this.place = parcel.readString();

}

public int describeContents() {

return 0;

}

/**

* 将对象序列化为一个Parcel对象 可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,

* 再通过createFromParcel从流里读取对象 注意:写的顺序和读的顺序必须一致。

*/

public void writeToParcel(Parcel parcel, int arg1) {

parcel.writeString(name);

parcel.writeInt(age);

parcel.writeString(place);

}

public static final Parcelable.Creator<HarlanInfo> CREATOR = new Creator<HarlanInfo>() {

public HarlanInfo createFromParcel(Parcel parcel) {

HarlanInfo harlan=new HarlanInfo(parcel);

return harlan;

}

@Override

public HarlanInfo[] newArray(int size) {

// TODO Auto-generated method stub

return new HarlanInfo [size];

}

};

HarlanInfo.aidl

package com.harlan.demo.aidl;

parcelable HarlanInfo;

定义一个aidl文件,使client端利用回调拿到service的param参数;然后设置到toast上显示出来。

ICallBack.aidl:

package com.harlan.demo.aidl;

interface ICallBack{

void handleByServer(String param);

}

定义这个aidl文件,使client用harlanInfo(client)传数据和到service,service用harlanInfo(service)取得数据;

ExecuteServiceAIDL.aidl:

package com.harlan.demo.aidl;

import com.harlan.demo.aidl.HarlanInfo;

import com.harlan.demo.aidl.ICallBack;

interface ExecuteServiceAIDL

{

/**

*get info from server and

*Transfer a callback methods handle;

*if occur error ,will be return null

*对于非基本数据类型和String和CharSequence类型,要加上方向指示

*包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。

*/

HarlanInfo getServerHarlanInfo(in HarlanInfo info,ICallBack icallback);

}

ClientActivity.java:

package com.harlan.demo.activity;

import android.app.Activity;

import android.content.ComponentName;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

import com.harlan.demo.aidl.ExecuteServiceAIDL;

import com.harlan.demo.aidl.HarlanInfo;

import com.harlan.demo.aidl.ICallBack;

public class ClientActivity extends Activity

{

public static final String TAG = "ClientActivity";

private static final String BIND_ACTION = "com.harlan.demo.aidl.service";

private EditText mEditTextName;

private EditText mEditTextAge;

private EditText mEditTextPlace;

private Button mButtonCommit;

private ExecuteServiceAIDL executeService;

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_client);

getView();

mButtonCommit.setOnClickListener(new View.OnClickListener()

{

@Override

public void onClick(View v)

{

getServiceConnect();

}

});

}

private void getView()

{

mEditTextName = (EditText)findViewById(R.id.editText_name);

mEditTextAge = (EditText)findViewById(R.id.editText_age);

mEditTextPlace = (EditText)findViewById(R.id.editText_place);

mButtonCommit = (Button)findViewById(R.id.button_commit);

}

private void getServiceConnect()

{

Intent it = new Intent();

it.setAction(BIND_ACTION);

startService(it);

bindService(it, mserviceConnection, BIND_AUTO_CREATE);

}

ServiceConnection mserviceConnection = new ServiceConnection()

{

@Override

public void onServiceDisconnected(ComponentName name)

{

Log.d(TAG, "onServiceDisconnected");

}

@Override

public void onServiceConnected(ComponentName name, IBinder service)

{

Log.d(TAG, "onServiceConnected");

executeService = ExecuteServiceAIDL.Stub.asInterface(service);

if (executeService != null)

{

handlerInfo();

}

}

};

private void handlerInfo()

{

String mName;

int mAge;

String mPlace;

if (mEditTextName.getText().toString().equals(""))

{

mName = "孤独";

}

else

{

mName = mEditTextName.getText().toString();

}

if (mEditTextAge.getText().toString().equals(""))

{

mAge = 23;

}

else

{

mAge = Integer.parseInt(mEditTextAge.getText().toString());

}

if (mEditTextPlace.getText().toString().equals(""))

{

mPlace = "世界";

}

else

{

mPlace = mEditTextPlace.getText().toString();

}

//将数据传到harlanInfo中

HarlanInfo mInfo = new HarlanInfo();

mInfo.setName(mName);

mInfo.setAge(mAge);

mInfo.setPlace(mPlace);

try

{

HarlanInfo serverInfo = new HarlanInfo();

serverInfo = executeService.getServerHarlanInfo(mInfo, mCallBack);

//拿到service传回的数据

mEditTextName.setText(serverInfo.getName());

mEditTextAge.setText(String.valueOf(serverInfo.getAge()));

mEditTextPlace.setText(serverInfo.getPlace());

unbindService(mserviceConnection);

}

catch (RemoteException e)

{

e.printStackTrace();

}

}

ICallBack.Stub mCallBack = new ICallBack.Stub()

{

@Override

public void handleByServer(String param)

throws RemoteException

{

Toast.makeText(getApplicationContext(), param, Toast.LENGTH_LONG).show();

}

};

}

AIDLService.Java:

package com.harlan.demo.service;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

import com.harlan.demo.aidl.ExecuteServiceAIDL;

import com.harlan.demo.aidl.HarlanInfo;

import com.harlan.demo.aidl.ICallBack;

public class AIDLService extends Service

{

public static final String TAG = "AIDLService";

private ICallBack mCallBack;

/**

* 绑定服务

*/

@Override

public IBinder onBind(Intent intent)

{

// TODO Auto-generated method stub

return mBinder;

}

/**

* 创建服务

*/

@Override

public void onCreate()

{

super.onCreate();

}

/**

* 销毁服务

*/

@Override

public void onDestroy()

{

super.onDestroy();

}

/**

* 启动服务

*/

@Override

public void onStart(Intent intent, int startId)

{

super.onStart(intent, startId);

}

/**

* 解绑服务

*/

@Override

public boolean onUnbind(Intent intent)

{

mCallBack = null;

return super.onUnbind(intent);

}

ExecuteServiceAIDL.Stub mBinder = new ExecuteServiceAIDL.Stub()

{

@Override

public HarlanInfo getServerHarlanInfo(HarlanInfo info, ICallBack icallback)

throws RemoteException

{

Log.d(TAG,"getServerHarlanInfo");

mCallBack = icallback;

//传参数给client

mCallBack.handleByServer("The msg is from server");

HarlanInfo newInfo = new HarlanInfo();

//通过HarlanInfo序列化数据 再传给client

newInfo.setName(info.getName()+"幸福");

newInfo.setAge(info.getAge() + 10);

newInfo.setPlace(info.getPlace()+"Home");

return newInfo;

}

};

}

效果图,布局文件自己写

ps:本人也是参考别人的例子写的,中间有解释不对的地方,望轻喷。。。。

时间: 2024-10-11 15:47:54

Android AIDL 实现过程的相关文章

【转】android程序编译过程

现在很多人想对Android工程的编译和打包进行自动化,比如建立每日构建系统.自动生成发布文件等等.这些都需要我们对Android工程的编译和打包有一个深入的理解,至少要知道它的每一步都做了什么,需要什么环境和工具,输入和输出是什么.那么我们就来挖掘一下Android的编译过程中的细节. 首先,我们假定你的系统(什么系统都行,不限于Linux还是Windows系统,当然,我在这里默认使用Linux系统来举例子,但在 Windows中几乎没有什么差别)已经安装了JDK和Android SDK.再假

Android应用构建过程解析

要得心应手地进行Android应用开发需要我们对Android工程的编译和打包有一个比较深入的理解,例如知道它的每一步都做了什么,需要什么环境和工具,输入和输出是什么,等等. 在前文<命令行下Android应用开发>中我们已经知道如何创建一个Android工程和编译运行可调试版本的应用程序.本文将介绍Android工程的整个编译过程. 首先来分析Ant如何将Android工程编译打包成APK文件 执行ant debug命令时ant 脚本build.xml各target之间的依赖关系图 执行an

(转载)你真的理解Android AIDL中的in,out,inout么?

前言 这其实是一个很小的知识点,大部分人在使用AIDL的过程中也基本没有因为这个出现过错误,正因为它小,所以在大部分的网上关于AIDL的文章中,它都被忽视了--或者并没有,但所占篇幅甚小,且基本上都是官方文档的译文,译者读者其实都不知其然.这几天在研究AIDL,偏偏我又是个执拗的性子,遇着不清不楚的东西就是想把它捋清楚,就下了些功夫研究了下AIDL中的定向tag,研究了下它的 in , out , inout . 整理而成此博文. 1.概述 首先要说的是定向tag是AIDL语法的一部分,而 in

android Apk打包过程概述_android是如何打包apk的

最近看了老罗分析android资源管理和apk打包流程的博客,参考其他一些资料,做了一下整理,脱离繁琐的打包细节和数据结构,从整体上概述了apk打包的整个流程. 流程概述: 1.打包资源文件,生成R.java文件 2.处理aidl文件,生成相应java 文件 3.编译工程源代码,生成相应class 文件 4.转换所有class文件,生成classes.dex文件 5.打包生成apk 6.对apk文件进行签名 7.对签名后的apk文件进行对其处理 打包过程使用的工具 名称 功能介绍 在操作系统中的

Android AIDL使用详解_Android IPC 机制详解

一.概述 AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于定义服务器和客户端通信接口的一种描述语言,可以拿来生成用于IPC的代码.从某种意义上说AIDL其实是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此而生成的一个IInterface的实例代码,AIDL其实是为了避免我们重复编写代码而出现的一个模板 设计AIDL这门语言的目的就是为了实现进程间通信.在Android系统中,每个进程

Android APP 调试过程中遇到的问题。

调试过过程中APP安装完启动后有的时候会异常退出,报这个错误.有的时候可以直接启动.查找不到原因.网上说把commit方法替换成commitAllowingStateLoss() 也无效. Android APP 调试过程中遇到的问题. >> android 这个答案描述的挺清楚的:http://www.goodpm.net/postreply/android/1010000007192169/AndroidAPP调试过程中遇到的问题.html

Android AIDL开发

Introduction   在Android中, 每个应用程序都运行在自己的进程中,拥有独立的内存空间.但是有些时候我们的应用程序需要跟其它的应用程序进行通信,这个时候该怎么办呢?显然, Java中不允许跨进程内存共享.无法直接交换数据.Android中可以采用AIDL的方式实现进程间通信(interprocess communication(IPC)). Android Developer原文介绍如下:AIDL (Android Interface Definition Language)

Android AIDL使用详解

1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口 icp:interprocess communication :内部进程通信 2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?文档/android-sdk/docs/guide/developing/tools/aidl.html中对步骤作了详细描述: --1.Create

Using self-defined Parcelable objects during an Android AIDL RPC / IPC call

Using self-defined Parcelable objects during an Android AIDL RPC / IPC call In my previous post “Using the Android Interface Definition Language (AIDL) to make a Remote Procedure Call (RPC) in Android” I’ve explained the basics on how inter-process c