androidaidl,Android aidl校验

Android:AIDL进程间通信基本框架

在某些业务场景下,我们需要在应用中单独开启一个进程进行一些操作。比如性能监控,如果让原始业务和性能监控本身的业务跑在同一个进程下,那么就会导致性能统计的数据的失真。

“真诚服务,让网络创造价值”是我们的服务理念,创新互联公司团队10多年如一日始终坚持在网站建设领域,为客户提供优质服。不管你处于什么行业,助你轻松跨入“互联网+”时代,PC网站+手机网站+公众号+小程序制作

而进程间通信,一般采用AIDL机制的客户端与服务端通信。

AIDL只能传递如下几类数据:

当传递自定义 Parcelable 时,有三处地方需要注意:

当传递其他 aidl 接口时,同样必须要 import 这个 aidl 文件

编写完 aidl 文件后,make一下工程,会在 build 下的 generated 下的 source 下的 aidl 目录生成对应的接口类文件。aidl 接口其实就是 API 接口,通过实现对应接口类的 Stub 子类来实现具体的 API 逻辑;通过对应接口类的 Stub 子类的 asInterface 方法得到具体的实现类,调用具体的 API 方法。

一个基本的客户端服务端的通信结构一般包括如下功能

客户端的功能

服务端的功能

客户端的相关功能实现比较简单,麻烦的是服务端的功能。因为 AIDL 接口定义的都是服务端的接口,是由客户端来调用的。而想要实现服务端反向调用客户端则需要通过其他手段实现。

想要实现服务端主动连接客户端,最好的办法就是 服务端发送广播,客户端收到广播后再主动连接服务端 ,通过这种方式变相地实现服务端主动连接客户端的功能

想要实现服务端主动断开客户端,除了上面 发送广播是一种实现方式外,还可以通过 android 的系统API RemoteCallbackList,用包名作为key值来注册远程回调接口的方式,让服务端持有客户端的回调接口,服务端调用回调接口,客户端在回调接口中实现主动断开服务端 ,通过这种方式变量地实现服务端主动断开客户端的功能。而采用后者会显得更加优雅

既然所有的操作归根结底都是由客户端来完成的,那么客户端必须得有如下的功能模块:

服务端必须得有的功能模块:

那么,整体的通信流程就是如下的步骤:

首先是通信的 aidl 接口定义

然后是客户端的连接操作与断开连接操作,包括广播接收者的注册以及回调接口的实现

然后是客户端的拉取数据和推送数据操作

接着是服务端的 iBinder 接口的实现,完成回调接口的注册、业务子线程的开启和关闭、数据的推送和数据的拉取操作

然后是服务端的主动连接和主动断开连接操作

最后是服务端的 onUnbind 方法的实现,对回调接口进行反注册

服务端模仿 FloatViewPlugin 自定义插件,实现 IServicePlugin 接口,定制个性化的悬浮窗插件

客户端在 Appliaction 的 onCreate方法中初始化

在 MainActivity 上实现连接、断开、数据通信

android进阶-AIDL之接口注册/解注册

AIDL-基本使用

AIDL-自定义数据类型

AIDL-修饰符in,out,inout

AIDL-重连方法

AIDL-接口注册/解注册

AIDL-连接池

为什么要特意讲解一下接口的注册与取消注册呢,因为在使用AIDL进程跨进程通信的时候, 每次传递的接口对象在内存中的地址都是不一样的 ,所以在注册了之后,无法使用常规的方式去取消, 因为注册和解注册传递的接口地址都不一样 ,系统无法识别

由于上面的问题,AIDL中提供了一个专门解决上述情况的类 RemoteCallbackList ,其工作原理就是:

首先,在前面讲解 AIDL的基本使用 的基础上先增加新的AIDL接口以及注册和解注册方法:

然后就是 RemoteCallbackList 的使用方法了:

注册/解注册很简单

接着是使用接口的方式:

ps: 需要注意的是 beginBroadcast() 方法和 finishBroadcast() 方法 必须配合使用 ,哪怕只是简单的获取集合大小

使用AIDL进行跨进程间通信中,往往我们是需要注册监听,让服务端通知的,但是服务端也必须提供解注册的方法,不然客户端如果离开某个界面不想再接受消息了,虽然直接离开不做处理客户端这边不会出错,但是服务端那边的监听集合还存在之前的,那么就会浪费系统资源,所以有注册监听的时候,最好也要实现解注册的方法

《Android开发艺术探索》

android之AIDL介绍

AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。

可以看出,AIDL是一种语言。

设计AIDL这门语言的目的是为了实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信。

每一个进程都有自己的Dalvik VM实例,都有自己的一块独立的内存,都在自己的内存上存储自己的数据,执行着自己的操作,都在自己的那片狭小的空间里过完自己的一生。

每个进程之间都你不知我,我不知你,就像是隔江相望的两座小岛一样,都在同一个世界里,但又各自有着自己的世界。

而AIDL,就是两座小岛之间沟通的桥梁。

我们可以通过AIDL来制定一些规则,规定它们能进行哪些交流——比如,它们可以在我们制定的规则下传输一些特定规格的数据。

通过这门语言,可以愉快的在一个进程访问另一个进程的数据,甚至调用它的一些方法,当然,只能是特定的方法。

默认支持的数据类型包括:

AIDL实例文件:

android怎么写aidl文件

建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:

(1)在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。详细介绍见实例52的内容。

(2)如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。

(3)建立一个服务类(Service的子类)。

(4)实现由aidl文件生成的Java接口。

(5)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,action标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。

建立AIDL服务

本例中将建立一个简单的AIDL服务。这个AIDL服务只有一个getValue方法,该方法返回一个String类型的值。在安装完服务后,会在客户端调用这个getValue方法,并将返回值在TextView组件中输出。建立这个AIDL服务的步骤如下:

(1)建立一个aidl文件。在Java包目录中建立一个IMyService.aidl文件。IMyService.aidl文件的位置如图

IMyService.aidl文件的内容如下:

Java代码:

package eoe.demo;

interface IMyService {

String getValue();

}

IMyService.aidl文件的内容与Java代码非常相似,但要注意,不能加修饰符(例如,public、private)、AIDL服务不支持的数据类型(例如,InputStream、OutputStream)等内容。

(2)如果IMyService.aidl文件中的内容输入正确,ADT会自动生成一个IMyService.java文件。读者一般并不需要关心这个文件的具体内容,也不需要维护这个文件。关于该文件的具体内容,读者可以查看本节提供的源代码。

(3)编写一个MyService类。MyService是Service的子类,在MyService类中定义了一个内嵌类(MyServiceImpl),该类是IMyService.Stub的子类。MyService类的代码如下:

Java代码:

package eoe.demo;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.os.RemoteException;

public class MyService extends Service {

public class MyServiceImpl extends IMyService.Stub {

@Override

public String getValue() throws RemoteException {

return "Android/OPhone开发讲义";

}

}

@Override

public IBinder onBind(Intent intent) {

return new MyServiceImpl();

}

}

在编写上面代码时要注意如下两点:

IMyService.Stub是根据IMyService.aidl文件自动生成的,一般并不需要管这个类的内容,只需要编写一个继承于IMyService.Stub类的子类(MyServiceImpl类)即可。

onBind方法必须返回MyServiceImpl类的对象实例,否则客户端无法获得服务对象。

(4)在AndroidManifest.xml文件中配置MyService类,代码如下:

Java代码:

service android:name=".MyService"

intent-filter

action android:name="net.blogjava.mobile.aidl.IMyService" /

/intent-filter

/service

下面来编写客户端的调用代码。首先新建一个Eclipse Android工程(ch08_aidlclient),并将自动生成的IMyService.java文件连同包目录一起复制到ch08_aidlclient工程的src目录中,如图所示。

调用AIDL服务首先要绑定服务,然后才能获得服务对象,代码如下:

Java代码:

package net.blogjava.mobile;

import net.blogjava.mobile.aidl.IMyService;

import android.app.Activity;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle; import android.os.IBinder;

import android.view.View; import android.view.View.OnClickListener;

import android.widget.Button; import android.widget.TextView;

public class Main extends Activity implements OnClickListener {

private IMyService myService = null;

private Button btnInvokeAIDLService;

private Button btnBindAIDLService;

private TextView textView;

private ServiceConnection serviceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

// 获得服务对象

myService = IMyService.Stub.asInterface(service);

btnInvokeAIDLService.setEnabled(true);

}

@Override

public void onServiceDisconnected(ComponentName name) {

}

};

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.btnBindAIDLService:

// 绑定AIDL服务

bindService(new Intent("net.blogjava.mobile.aidl.IMyService"), serviceConnection, Context.BIND_AUTO_CREATE);

break;

case R.id.btnInvokeAIDLService:

try {

textView.setText(myService.getValue());

// 调用服务端的getValue方法

} catch (Exception e) {

}

break;

}

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService);

btnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService); btnInvokeAIDLService.setEnabled(false);

textView = (TextView) findViewById(R.id.textview);

btnInvokeAIDLService.setOnClickListener(this);

btnBindAIDLService.setOnClickListener(this);

}。

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 your .aidl file - This file defines an interface (YourInterface.aidl) that defines the methods and fields available to a client.

创建你的aidl文件,我在后面给出了一个例子,它的aidl文件定义如下:写法跟java代码类似,但是这里有一点值得注意的就是它可以引用其它aidl文件中定义的接口,但是不能够引用你的java类文件中定义的接口

package com.cao.android.demos.binder.aidl;

import com.cao.android.demos.binder.aidl.AIDLActivity;

interface AIDLService {

void registerTestCall(AIDLActivity cb);

void invokCallBack();

}

--2.Add the .aidl file to your makefile - (the ADT Plugin for Eclipse manages this for you). Android includes the compiler, called AIDL, in the tools/ directory.

编译你的aidl文件,这个只要是在eclipse中开发,你的adt插件会像资源文件一样把aidl文件编译成java代码生成在gen文件夹下,不用手动去编译:编译生成AIDLService.java如我例子中代码

--3.Implement your interface methods - The AIDL compiler creates an interface in the Java programming language from your AIDL interface. This interface has an inner abstract class named Stub that inherits the interface (and implements a few additional methods necessary for the IPC call). You must create a class that extends YourInterface.Stub and implements the methods you declared in your .aidl file.

实现你定义aidl接口中的内部抽象类Stub,public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService

Stub类继承了Binder,并继承我们在aidl文件中定义的接口,我们需要实现接口方法,下面是我在例子中实现的Stub类:

private final AIDLService.Stub mBinder = new AIDLService.Stub() {

@Override

public void invokCallBack() throws RemoteException {

Log("AIDLService.invokCallBack");

Rect1 rect = new Rect1();

rect.bottom=-1;

rect.left=-1;

rect.right=1;

rect.top=1;

callback.performAction(rect);

}

@Override

public void registerTestCall(AIDLActivity cb) throws RemoteException {

Log("AIDLService.registerTestCall");

callback = cb;

}

};

Stub翻译成中文是存根的意思,注意Stub对象是在被调用端进程,也就是服务端进程,至此,服务端aidl服务端得编码完成了。

--4.Expose your interface to clients - If you're writing a service, you should extend Service and override Service.onBind(Intent) to return an instance of your class that implements your interface.

第四步告诉你怎么在客户端如何调用服务端得aidl描述的接口对象,doc只告诉我们需要实现Service.onBind(Intent)方法,该方法会返回一个IBinder对象到客户端,绑定服务时不是需要一个ServiceConnection对象么,在没有了解aidl用法前一直不知道它是什么作用,其实他就是用来在客户端绑定service时接收service返回的IBinder对象的:

AIDLService mService;

private ServiceConnection mConnection = new ServiceConnection() {

public void onServiceConnected(ComponentName className, IBinder service) {

Log("connect service");

mService = AIDLService.Stub.asInterface(service);

try {

mService.registerTestCall(mCallback);

} catch (RemoteException e) {

}

}

public void onServiceDisconnected(ComponentName className) {

Log("disconnect service");

mService = null;

}

};

mService就是AIDLService对象,具体可以看我后面提供的示例代码,需要注意在客户端需要存一个服务端实现了的aidl接口描述文件,但是客户端只是使用该aidl接口,不需要实现它的Stub类,获取服务端得aidl对象后mService = AIDLService.Stub.asInterface(service);,就可以在客户端使用它了,对mService对象方法的调用不是在客户端执行,而是在服务端执行。

4.aidl中使用java类,需要实现Parcelable接口,并且在定义类相同包下面对类进行声明:

上面我定义了Rect1类

之后你就可以在aidl接口中对该类进行使用了

package com.cao.android.demos.binder.aidl;

import com.cao.android.demos.binder.aidl.Rect1;

interface AIDLActivity {

void performAction(in Rect1 rect);

}

注意in/out的说明,我这里使用了in表示输入参数,out没有试过,为什么使用in/out暂时没有做深入研究。

转载


分享名称:androidaidl,Android aidl校验
当前网址:http://cdiso.cn/article/dsipdsi.html

其他资讯