• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android基础部分再学习--AIDL

android基础部分再学习--AIDL

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android基础部分再学习--AIDL等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android基础部分再学习--AIDL


AIDL与其他IDL语言类似,你需要做一些工作。 它允许你定义客户端与服务端达成一致的程序接口使用进程间通信相互交流。 在ANdroid上面,一个进程不能正常的访问另一个进程的内存。 所以说,他们需要分解他们的对象为操作系统可以理解的基本单位,然后为你把这些对象按次序跨越进程边界 书写这些代码是单调冗长的,所以android使用AIDL为你处理这个问题。

注意:使用AIDL只有在你允许来自不同应用的客户端跨进程通信访问你的service,并且想要在你的service种处理多线程的时候才是必要的。 如果你不需要执行不同应用之间的IPC并发,你应该通过实现Binder建立你的接口,或者如果你想执行IPC,但是不需要处理多线程。那么使用Messenger实现你的接口 不管怎样,确保你在实现一个AIDL之前理解了Bound Service

在你设计你的AIDL接口之前,请注意调用一个AIDL接口是直接的函数调用 你不应该假设线程在哪个调用中发生 情形与依赖调用是来自一个本地进程中的线程还是一个远程进程中的线程相关 尤其是:

来自本地进程的调用与调用者在同一个线程中执行。 如果这是你的主UI线程,线程继续在AIDL接口中执行 如果是其他的线程,则它是一个在service中执行你的代码的线程 这样,如果只是本地线程访问这个service,你完全可以控制哪些线程在其中执行(但是如果是那样的话,那么你压根就不应该使用AIDL,而应该通过实现Binder建立接口) 平台在你自己的进程中内部维护一个线程池中分配的远程进程的调用 你必须为从未知线程发出的即将到来的调用,并且是伴随同时多个调用做好准备 换句话说,AIDL接口的实现必须是完全的线程安全的 单向关键词限定了远程调用的行为 使用的时候,一个远程调用不会被阻塞;它只是简单的发送传输数据并且立即返回 最终接口的实现把它作为一个来自Binder线程池的常规调用、一个普通的远程调用来接收 如果本地调用使用单向的,那么就不会有影响,并且调用仍然是异步的

定义一个AIDL接口


你必须在一个.aidl文件中使用java编程语言语法定义你的AIDL接口,然后在提供service的应用中和任何绑定到这个service的应用中的源代码中(在src目录吓)保存它

当你编译包含.aidl文件的应用时,Android SDK工具基于这个.aidl文件生成一个IBinder接口,并且把它保存到项目的gen目录吓 service必须恰当的实现这个IBinder接口 之后客户端应用可以绑定到这个服务上,然后从IBinder调用方法来执行IPC

使用AIDL建立一个邻接的service需要遵循下面的步骤

1.建立.aidl文件

这个文件使用方法签名定义了语言接口

2.实现这个接口

Android SDk工具基于你的.aidl文件使用java语言生成一个接口 这个接口有一个内部抽象类,叫做Stub,它是继承Binder并且实现你AIDL接口的 你必须继承这个Stub类并且实现这些方法

3.暴露这个接口给客户端

实现一个service并且覆盖onBind()方法返回你的Stub实现类

警告:在你第一次发布AIDL之后的其中任何的改变必须保持向后兼容来避免破坏其他应用程序使用你的service 也就是说,因为你的.aidl文件必须被复制到其他应用程序中来让他们访问你service的接口,你必须维护原始接口的支持。

1.建立.aidl文件

AIDL使用一个简单的语法让你声明一个带有一个或者多个带有参数和返回值方法的接口 参数和返回值可以是任何类型,甚至是AIDL生成的接口

你必须使用java语言构建.aidl文件 每一个.aidl文件必须定义一个简单的接口并且要求只有接口声明和方法签名

默认的,AIDL支持下面数据类型:

ava语言中的所有基本数据类型(比如int、long、char、boolean等等) String CharSequence List

List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是你定义的parcelable List可以使用范型(例如,List) 接收端的实际类经常是一个ArrayList,尽管方法是使用List接口生成的

Map

Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是你定义的parcelable 范型map是不被支持的(比如这种形式Map) 接收端的实际类经常是一个HashMap,尽管方法是使用Map接口生成的

对于上述类型之外的类型,你必须声明import,即使在同一个包内。

当定义你的service接口的时候,注意:

方法可以接收0或多个参数,并且有返回值或者返回void 所有非基本数据类型要求要求一个定向的tag来指定数据是去往哪个方向的 无论是输入、输出,还是输入输出(参加下面的例子) 基本数据类型是默认支持的,并且不能是其他的。

 

警告:你应该限制方向于真正需要的地方,因为排列整理参数的开销是很昂贵的。

.aidl文件中的所有的代码注释都在生成的IBinder接口中(除了在import和包声明之前的注释) 只支持方法,你不可以在AIDL暴露静态域

这有个.aidl文件的例子:

// IRemoteService.aidl
package com.example.android;

// Declare any non-default types here with import statements

/** Example service interface */
interface IRemoteService {
    /** Request the process ID of this service, to do evil things with it. */
    int getPid();

    /** Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

简单的保存你的.aidl文件在你工程的src目录下,当你build你的应用时,SDK工具在你工程的gen目录下生成IBinder接口文件 生成的文件名字与.aidl名字匹配,但是是以.java为扩展名(例如IRemoteService.aidl对应为IRemoteService.java)

如果你使用Eclipse,增量编译几乎是立刻生成binder类。如果你不使用Eclipse,那么Ant工具在你下次编译你的应用(你应该使用ant debug或者ant release编译你的工程)时生成binder类。一旦你写好了.aidl文件,你的代码就可以链接到生成的类上面了。

2.实现接口

当你编译你的应用时,Android SDK工具生成一个.java接口文件用你的.aidl文件命名 生成的接口包含一个名字为Stub的子类(比如YourInterface.Stub),这是一个它父类的抽象实现,并且声明了.aidl中所有的方法

注意:Stub也定义了一些辅助的方法,最显著的就是asInterface(),它是用来接收一个IBinder(通常IBinder传递给客户端的onServiceConnected()回调方法)并且返回一个Stub接口的实例 更多细节参考Calling an IPC Method章节。

为了实现来自.aidl文件生成的接口,需要继承Binder接口(例如YourInterface.Stub)并且实现从.aidl文件中继承的方法。

这有一个使用匿名实例实现一个叫IRemoteService(定义在IRemoteService.aidl中,例子如上)的接口的例子

private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
    public int getPid(){
        return Process.myPid();
    }
    public void basicTypes(int anInt, long aLong, boolean aBoolean,
        float aFloat, double aDouble, String aString) {
        // Does nothing
    }
};

mBinder是一个Stub类的实例

当实现你的AIDL接口的时候有很多规则需要注意

调用不保证在主线程中执行,所以你需要一开始就考虑多线程并且适当的build你的service为线程安全的 默认的,RPC调用是同步的。 如果你知道service需要花费一些时间来完成请求,你就不应该从activity的主线程中调用它,因为它可能使得应用没有响应(Android也许会显示一个ANR的对话框),通常你应该在客户端中一个单独的线程调用它 抛出的异常不会返回给调用者

3.暴露接口给客户端

一旦你为service实现了接口,你需要把它暴露给客户端,这样他们才能绑定到上面 为了给你的service暴露接口,继承Service并且实现onBind()方法返回一个你实现生成的Stub类(像我们在上一结讨论的那样) 这有一个service暴露IRemoteService接口给客户端的例子

public class RemoteService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return the interface
        return mBinder;
    }

    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
        public int getPid(){
            return Process.myPid();
        }
        public void basicTypes(int anInt, long aLong, boolean aBoolean,
            float aFloat, double aDouble, String aString) {
            // Does nothing
        }
    };
}

现在,当一个客户端(比如一个activity)调用bindService()来连接到这个service,这个客户端的onServiceConnected()回调函数接收service中onBind()方法返回的mBinder实例

客户端必须可以访问接口类,所以如果客户端和服务端在不同的应用中,那么客户端所在的应用必须有一份.aidl文件的副本在其src目录下(生成android.os.Binder接口,提供客户端访问AIDL方法都在这个目录下)

当客户端在onServiceConnected()回调方法中接收到IBinder时,它必须调用你的ServiceInterface.Stub.asInterface(service)来把返回参数映射到你的ServiceInterface类型上。例如:

IRemoteService 



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-26Android Studio 之 注释模板,androidstudio
  • 2017-05-26Android开发3:Intent、Bundle的使用和ListView的应用 、RelativeLayout(相对布局)简述(简单通讯录的实现),relativelayout
  • 2017-05-26关于Android滑动冲突的解决方法(二)
  • 2017-05-26实用的圆形图片控件ImageView,
  • 2017-05-26android内核剖析,android内核
  • 2017-05-26手势事件,html5手势事件
  • 2017-05-26android:Activity数据传递之基本数据类型
  • 2017-05-26Android 手机卫士--自定义属性,android卫士
  • 2017-05-26MSM8909+Android5.1.1键盘驱动---sn7326介绍
  • 2017-05-26zoom动画,实现图片点击预览效果,zoom预览

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 仿QQ空间根据位置弹出PopupWindow显示更多操作效果,popupwindow
    • 6.3.1 数据存储与访问之——初见SQLite数据库
    • TiemPicke 和 DatePicker控件 自定义大小
    • android获取屏幕宽高与获取控件宽高,android获取控件
    • Kotlin与Android SDK 集成(KAD 05),kotlinandroid
    • Android常用学习网站,android
    • Remote Displayer for Android V1.0,displayerandroid
    • 配置Nginx反向代理Exchange 2007上的OWA
    • 和我一起看API(一)你所不知道的LinearLayout补充,apilinearlayout
    • 【android开发笔记】为Button的背景图片添加边框式样式效果,

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有