2015年1月6日星期二

Android开发-API指南-AIDL - 呆呆大虾

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Android开发-API指南-AIDL - 呆呆大虾  阅读原文»

Android Interface Definition Language (AIDL)

英文原文:http://developer.android.com/guide/components/aidl.html
采集日期:2014-12-31
另一位兄弟的早期博文(不准确,供参考):http://www.cnblogs.com/over140/archive/2011/03/08/1976890.html

Android 接口定义语言 AIDL(Android Interface Definition Language)与其他已有的 IDL 很类似。 客户端和服务端可以通过由它定义的编程接口来达成共识,以便通过进程间通讯(IPC)完成相互通讯。 在 Android 系统中,通常一个进程不允许直接访问另一个进程的内存。 因此为了能够实现对话,进程需要把对象分解为操作系统可以识别的原生数据,在跨越进程边界后再组装起来。 实现组装的代码非常枯燥无趣,因此 Android 通过 AIDL 可有助于完成这一过程。

注意: 仅当允许其他应用程序通过 IPC 方式访问服务,并且服务需要多线程运行时,才必须用到 AIDL。 如果不需要进行跨越多个应用的并发 IPC,就应该用 实现绑定 实现接口。或者要进行 IPC 但需要多线程运行,则可 使用 Messenger 来实现接口。 无论如何,在实现 AIDL 之前,请确认已经理解了 Bound 服务 中的内容。

在开始设计 AIDL 接口之前,请务必注意,对 AIDL 接口的调用是直接函数调用(direct function call)。 发起调用的线程根本无法预料。 根据发起调用的线程是在本地进程还是在远程进程,处理方式也将不同。 具体来说:

  • 如果从本地进程发起,则调用将在发起线程中运行。 如果是主 UI 线程发起的,则其将继续运行 AIDL 接口。 如果是其他线程发起的,则为运行服务代码的线程。 因此,如果只有本地线程需要访问服务,则可以完全控制在哪个线程运行(但如果是这样,就根本不应该使用 AIDL 了,而应该通过 实现 Binder 来创建接口)。
  • 从远程进程发起的调用,将会由系统维护的本地进程内部的线程池分发。 必须准备好迎接来自未知线程的调用,并且还可能同时收到多个调用。 换句话说, AIDL接口的实现必须完全是线程安全的。
  • 关键字oneway会改变远程调用的处理方式。 使用该关键字时,远程调用将不会阻塞,在发送完交易数据它就会立即返回。 接口的实现代码最终将这种远程调用视同由 Binder 线程池发起的调用一样接收。 如果在本地调用中使用了oneway,则不起作用,调用仍旧是同步执行的。

定义 AIDL 接口

只能在.aidl文件中使用 Java 语法定义 AIDL 接口, 并且在服务所在应用和其他需要绑定服务的应用中,均保存为源代码文件(在src/目录下)。

在编译包含.aidl文件的应用时, Android SDK 工具会根据 .aidl文件生成一个 IBinder 接口,并将它保存在项目的gen/目录下。 服务端必须根据需要实现 IBinder。 然后客户端应用就能与服务绑定,并利用 IBinder 调用方法实现 IPC 。

要利用 AIDL 创建一个可被绑定的服务,请按照以下步骤进行:

  1. 创建 .aidl 文件

    该文件定义了包含方法声明(Method Signature)的编程接口

  2. 实现接口

    Android SDK 工具包会根据.aidl 文件生成 Java 语言格式的接口。 这个接口有一个名为Stub的内部抽象类,它扩展自 Binder ,并用于实现 AIDL 接口所要求的方法。 必须扩展这个Stub类并实现这些方法。

  3. 向客户端公布接口

    实现 Service 并重写 onBind() 方法,以便返回已实现的Stub类。

警告: 为了避免其他应用程序与服务的使用中断,在应用程序发布之后,对 AIDL 接口 所做的所有修改都必须保证与之前的定义兼容。 也就是说,因为.aidl必须复制给其他应用程序以便其访问服务接口,所以必须维持对以前接口的支持。

1. 创建 .aidl 文件

AIDL 的语法很简单,声明一个带有若干方法的接口即可,这些方法都可带有参数和返回值。 参数和返回值可以为任意类型,甚至可以是另一个由 AIDL 生成的接口。

.aidl 文件必须用 Java 语言编写。 每个.aidl文件中必须也只能定义一个接口,且只能包含接口的定义和方法声明。

默认情况下, AIDL 支持以下数据类型:

  • Java 语言的所有简单类型(如intlongcharboolean等等)
  • String
  • CharSequence
  • List

    List 中的所有数据只能是这里列出的类型、其他某个基于 AIDL 生成的接口、已声明的自定义 Parcelable 类。 List 还可被用作“泛型”(generic)类(如 List<String>)。 虽然方法是通过 List 接口生成的,但是实际收到的实体类其实会是一个 ArrayList

  • Map

    Map 中的所有数据只能是这里列出的类型、其他某个基于 AIDL 生成的接口、已声明的自定义 Parcelable 类。 这里不支持 Map 泛型(比如 Map<String,Integer> 的形式)。 虽然方法是通过 Map 接口生成的,但实际收到的实体类其实会是一个 HashMap

对于未列入上述列表的类型,即便是定义于接口所在的包中,也必须包含 import 语句。

在定义服务接口时,请注意:

  • 方法可以有多个参数,也可以不带参数;可有一个返回值,或无返回值(void)。
  • 所有非简单类型的参数都需要带有一个指明数据方向的标志。 可以是inoutinout(参阅下述例子)。

    简单类型的参数默认是 in ,且不能是其他方向值。

    注意: 请按照实际需求来限定参数的方向,因为参数的组装过程开销很大。

  • .aidl 文件中的代码注释都会一并放入最终生成的 IBinder 接口中( import 和 package 语句之前的注释除外)。
  • AIDL 中只支持方法,不能声明静态成员。

下面是一个 .aidl 文件示例:

1 // IRemoteService.aidl
2 package com.example.android;
C#中使用Redis学习二 在.NET4.5中使用redis hash操作 - 张文书  阅读原文»

上一篇>>

摘要


  上一篇讲述了安装redis客户端和服务器端,也大体地介绍了一下redis。本篇着重讲解.NET4.0 和 .NET4.5中如何使用redis和C# redis操作哈希表。并且会将封装的一些代码贴一下。在讲解的过程中,我打算结合redis操作命令一起叙述,算是作为对比吧。这样也能让读者清楚了 解,所分装的代码对应的redis的哪一些操作命令。

hash哈希表简介


  这里仅仅是对哈希表作简单概念级介绍(摘自csdn),如果需要,自己去研究。

1、哈希表的概念

  哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度。这个映射函数就做散列函数,存放记录的数组叫做散列表。

2、哈希表查找的时间复杂度

  哈希表存储的是键值对,其查找的时间复杂度与元素数量多少无关,哈希表在查找元素时是通过计算哈希码值来定位元素的位置从而直接访问元素的,因此,哈希表查找的时间复杂度为O(1)。

如何在.NET4.0/4.5中安装redis组件?


  在上一篇博文中,安装好的redis服务器端,要记得开启服务。然后再在.NET4.5(.NET4.0同理)项目中添加对redis操作的dll文件的引用。引用的步骤如下:

第一步:右键项目中的引用,选择“管理NuGet程序包”;

第二步:在搜索栏中输入“Redis client for the Redis NoSQL DB”,联机查找;如下图:

  联机搜索结构中的第一个(如上图红色区域的组件,其版本号为4.0.35)就是要安装的组件了。接下来我们就继续点击“安装”按钮,进入下载组件,等下载完成后,继续选择“接受条款”,然后继续安装。安装过程中会出现下图情况:

  这句红色错误的意思是我们安装的ServiceStack.Interfaces 4.0.35版本与当前的.NET4.5框架中组件不兼容。这说明我们需要降低或是提高.NET版本解决此问题。我安装的是.NET4.5,所以我只能降低版本。降低.NET版本的方法大家应该都知道的。我就在累述一次,希望大家不要嫌烦,毕竟还有新手在。方法:右键项目文件选择“属性”==》“应用程序”==》“目标框架”,然后选择各个版本去尝试之前的两步操作,直到可以安装为止。

  我试过了,.NET4.0也会遇到同样问题,直到.NET3.5才可以。当然此时安装的ServiceStack.Interfaces 版本是1.0.0.0 ,这样我们再把.NET版本恢复4.5即可使用了。,其实是变相在.NET4.0/4.5下使用redis客户端。不知道各位有没有遇到这样的问题,还是直接拷贝别人的dll文件。当自己亲自去操作的时候,才会发现,其实就算是安装一个组件都可能会出现各种各样的问题。所以,要想了解全过程的话,我们还是要身体力行的啊。好了,这样就说明在.NET4.5下安装好了redis client了。

实战:在项目中运用redis代码详解


  这部分主要是讲解怎样连接到redis服务器。其中包含很多配置,我就用代码去说明一切了。配置文件如下代码:

1 <configSections>
2 <section name="RedisConfig" type="RedisDemo.Common.Redis.RedisConfigInfo, RedisDemo"/>
3 </configSections>
4 <RedisConfig WriteServerList="127.0.0.1:6379" ReadServerList="127.0.0.1:6379" MaxWritePoolSize="60"
  MaxReadPoolSize="60" AutoStart="true" LocalCacheTime="180" RecordeLog="false"/>

  在这里对RedisConfig这段配置文件的属性作下说明。

  WriteServerList:可写的Redis链接地址。

  ReadServerList:可读的Redis链接地址。

  MaxWritePoolSize:最大写链接数。

  MaxReadPoolSize:最大读链接数。

  AutoStart:自动重启。

  LocalCacheTime:本地缓存到期时间,单位:秒。

  RecordeLog:是否记录日志,该设置仅用于排查redis运行时出现的问题,如redis工作正常,请关闭该项。

  RedisConfigInfo类是记录redis连接信息,此信息和配置文件中的RedisConfig相呼应。cs代码如下:(这段代码不是我自己写的,但是我觉得应该这样设计。所以,copy了一下别人的代码。)

1 using System.Configuration;
2
3 namespace RedisDemo.Common.Redis
4 {
5 public sealed class RedisConfigInfo : ConfigurationSection
6 {
7 public static RedisConfigInfo GetConfig()
8 {
9 var section = (RedisConfigInfo)ConfigurationManager.GetSection("RedisConfig");
10 return section;
11 }
12 public static RedisConfigInfo GetConfig(string sectionName)
13 {
14 var section = (RedisConfigInfo)ConfigurationManager.GetSection("RedisConfig");
15 if (section == null)
16 {
17 throw

没有评论:

发表评论