| <html devsite><head> |
| <title>HIDL Java</title> |
| <meta name="project_path" value="/_project.yaml"/> |
| <meta name="book_path" value="/_book.yaml"/> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <p>Android O 对 Android 操作系统进行了重新架构,在独立于设备的 Android 平台与特定于设备和供应商的代码之间定义了清晰的接口。 |
| Android 已经以 HAL 接口的形式(在 <code>hardware/libhardware</code> 中定义为 C 标头)定义了许多此类接口。HIDL 将这些 HAL 接口替换为稳定的带版本接口,可以采用 Java(如下所述),也可以是采用 <a href="/devices/architecture/hidl-cpp/index.html">C++</a> 的客户端和服务器端 HIDL 接口。</p> |
| |
| <p>HIDL 接口主要通过本机代码使用,因此 HIDL 专注于自动生成高效的 C++ 代码。不过,HIDL 接口也必须能够直接通过 Java 使用,因为有些 Android 子系统(如 Telephony)很可能具有 Java HIDL 接口。</p> |
| |
| <p>本部分介绍了 HIDL 接口的 Java 前端,详细说明了如何创建、注册和使用服务,以及使用 Java 编写的 HAL 和 HAL 客户端如何与 HIDL RPC 系统进行交互。</p> |
| |
| <h2 id="client">作为客户端</h2> |
| <p>要访问软件包 <code>android.hardware.foo</code> 版本 1.0 中服务名称注册为 <code>foo-bar</code> 的接口 IFoo,请执行以下操作:</p> |
| |
| <ol> |
| <li>添加库: |
| |
| <ul> |
| <li>将以下内容添加到 Android.mk 中: |
| <pre class="prettyprint">LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java</pre> |
| |
| <strong>或</strong><br /> |
| </li> |
| |
| <li>将以下内容添加到 Android.bp 中: |
| <pre class="prettyprint"> |
| shared_libs: [ |
| /* … */ |
| "android.hardware.foo-V1.0-java", |
| ], |
| </pre> |
| 该库还存在静态版:<code>android.hardware.foo-V1.0-java-static</code>。</li> |
| </ul> |
| </li> |
| <li>将以下内容添加到您的 Java 文件中: |
| <pre class="prettyprint"> |
| import android.hardware.foo.V1_0.IFoo; |
| ... |
| IFoo server = IFoo.getService(); // throws exception if not available |
| IFoo anotherServer = IFoo.getService("second_impl"); |
| server.doSomething(…); |
| </pre> |
| </li> |
| </ol> |
| |
| <h2 id="service">提供服务</h2> |
| <p>Java 中的框架代码可能需要提供接口才能接收来自 HAL 的异步回调。</p> |
| |
| <p class="warning"><strong>警告</strong>:请勿用 Java 实现驱动程序 (HAL)。我们强烈建议您用 C ++ 实现驱动程序。</p> |
| |
| <p>对于软件包 <code>android.hardware.foo</code> 版本 1.0 中的接口 <code>IFooCallback</code>,您可以按照以下步骤用 Java 实现接口。</p> |
| |
| <ol> |
| <li>用 HIDL 定义您的接口。</li> |
| <li>打开 <code>/tmp/android/hardware/foo/IFooCallback.java</code> 作为参考。</li> |
| <li>为您的 Java 实现创建一个新模块。</li> |
| <li>检查抽象类 <code>android.hardware.foo.V1_0.IFooCallback.Stub</code>,然后编写一个新类以将其扩展,并实现抽象方法。</li> |
| </ol> |
| |
| <h3 id="autogen">查看自动生成的文件</h3> |
| <p>要查看自动生成的文件,请运行以下命令:</p> |
| <pre class="prettyprint"> |
| hidl-gen -o /tmp -Ljava \ |
| -randroid.hardware:hardware/interfaces \ |
| -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0 |
| </pre> |
| |
| <p>这些命令会生成目录 <code>/tmp/android/hardware/foo/1.0</code>。对于文件 <code>hardware/interfaces/foo/1.0/IFooCallback.hal</code>,这会生成文件 <code>/tmp/android/hardware/foo/1.0/IFooCallback.java</code>,其中包含 Java 接口、代理代码和存根(代理和存根均与接口吻合)。</p> |
| |
| <p><code>-Lmakefile</code> 会生成在构建时运行此命令的规则,允许您包含 <code>android.hardware.foo-V1.0-java(-static)?</code> 并链接到相应文件。您可以在 <code>hardware/interfaces/update-makefiles.sh</code> 中找到自动为充满接口的项目执行此操作的脚本。 |
| 本示例中的路径是相对路径;硬件/接口可能是代码树下的一个临时目录,让您能够先开发 HAL 然后再进行发布。</p> |
| |
| <h2 id="service">运行服务</h2> |
| <p>HAL 提供了一个接口 <code>IFoo</code>,它必须通过接口 <code>IFooCallback</code> 对框架进行异步回调。<code>IFooCallback</code> 接口不按名称注册为可检测到的服务;相反,<code>IFoo</code> 必须包含一个诸如 <code>setFooCallback(IFooCallback x)</code> 的方法。</p> |
| |
| <p>要通过软件包 <code>android.hardware.foo</code> 版本 1.0 设置 <code>IFooCallback</code>,请将 <code>android.hardware.foo-V1.0-java</code> 添加到 <code>Android.mk</code> 中。运行服务的代码为:</p> |
| |
| <pre class="prettyprint"> |
| import android.hardware.foo.V1_0.IFoo; |
| import android.hardware.foo.V1_0.IFooCallback.Stub; |
| .... |
| class FooCallback extends IFoo.Stub { |
| // implement methods |
| } |
| .... |
| // Get the service you will be receiving callbacks from. |
| // This also starts the threadpool for your callback service. |
| IFoo server = IFoo.getService(); // throws exception if not available |
| .... |
| // This must be a persistent instance variable, not local, |
| // to avoid premature garbage collection. |
| FooCallback mFooCallback = new FooCallback(); |
| .... |
| // Do this once to create the callback service and tell the "foo-bar" service |
| server.setFooCallback(mFooCallback); |
| </pre> |
| |
| <h2 id="extensions">接口扩展</h2> |
| <p>假设指定服务在所有设备上实现了接口 <code>IFoo</code>,那么该服务在特定设备上可能会提供在接口扩展 <code>IBetterFoo</code> 中实现的附加功能,即:</p> |
| |
| <pre class="prettyprint"> |
| interface IFoo { |
| ... |
| }; |
| |
| interface IBetterFoo extends IFoo { |
| ... |
| }; |
| </pre> |
| |
| <p>感知到扩展接口的调用代码可以使用 <code>castFrom()</code> Java 方法将基本接口安全地转换为扩展接口:</p> |
| |
| <pre class="prettyprint"> |
| IFoo baseService = Foo.getService(); |
| IBetterFoo extendedService = IBetterFoo.castFrom(baseService); |
| if (extendedService != null) { |
| // The service implements the extended interface. |
| } else { |
| // The service only implements the base interface. |
| } |
| </pre> |
| |
| </body></html> |