链接构建步骤(Xcode 的“Link Binary With Libraries”构建阶段)需要特定于 J2ObjC 的标志,这些标志因应用使用转换的 Java 类的方式而异。核心标记由 j2objcc 命令行脚本设置,但使用 Xcode 进行构建时需要指定。
SDK 库
J2ObjC 的 JRE 实现需要此库。如果未添加此库,将导致名称以 _iconv
开头的未定义符号错误。
媒体库 | 链接标记 | 说明 |
---|---|---|
iconv | -l 图标 | 供 jre_core 用于字符编码和解码。 |
这些库由 J2ObjC 的 JRE 实现使用,可能需要链接到您的应用。
媒体库 | 链接标记 | 说明 |
---|---|---|
zip | -l z | 由 java.util.zip 使用。如果您要链接 jre_zip,则需要包含此文件。 |
安全性 | -框架安全性 | 如果关联 jre_security,则是必需的。 |
图书馆搜索路径
J2ObjC 的发行版包含多个静态库;如需使用这些库,您的项目需要告知链接器在哪里可以找到这些库。
通常,库搜索路径需要包含 _$(j2objcdistribution)/lib,其中 _$(j2objcdistribution) 变量是 J2ObjC 的本地副本的路径。例如,如果您将 J2ObjC 版本归档文件解压缩到“/usr/local/”,则路径将为“/usr/local/j2objc”。
重要提示:请勿在项目中实际使用 _$(j2objcdistribution);始终指定 J2ObjC 的安装位置的实际路径。
如果您从 J2ObjC 的源代码副本构建,则 _$(j2objcdistribution) 将是副本的“j2objc/dist/”目录。在您使用 make dist
构建 J2ObjC 之前,此目录不存在。
Xcode:库搜索路径
通过添加 _$(j2objcdistribution)/lib(再次使用实际路径)来更新应用目标的库搜索路径。
JRE 库
这些库实现了 J2ObjC 的 JRE 模拟定义的类。
注意:libjre_core.a
库包含大多数其他子集中的类。如需缩减应用大小,建议先将应用与 -l jre_core
相关联,然后添加可解决任何缺失符号的子集库。例如,最常用的 java.io
类位于 libjre_core.a
中,因此,仅当存在名称以 JavaIo
开头的未解析符号错误时,才包含 libjre_io.a
库。
媒体库 | 链接标记 | 说明 |
---|---|---|
libjre_core.a | -l jre_core | J2ObjC 的 JRE 模拟所需的 最小类集,由所有已生成的源文件引用。如果翻译后的 Java 源代码引用了对网络、XML、SQL 等内容的 JRE 支持,则还需要关联其他库(见下文)。 |
libjre_beans.a | -l jre_beans |
java.beans 软件包中的
所有类。并非所有 Java Beans 类都包含在内,因为其中许多类仅供 Swing 和 AWT 应用使用。 |
libjre_channels.a | -l jre_channels |
java.nio.channels 和 java.nio.channels.spi 软件包中的
多个类。
|
libjre_concurrent.a | -l jre_concurrent |
java.util.concurrent 、java.util.concurrent.atomic 和 java.util.concurrent.locks 软件包中的
多个类。
|
libjre_icu.a | -l jre_icu |
android.icu 中的
多个类,以支持时区(主要用于启用 java.time )。
|
libjre_io.a | -l jre_io |
java.io 软件包中的
几个(不常用)的类。
|
libjre_net.a | -l jre_net |
java.net 软件包中的
多个类。不过,java.net.URLClassLoader 类位于 jre_security 中,而 javax.net 和 javax.net.ssl 类位于 jre_ssl 中。
|
libjre_security.a | -l jre_security |
java.security 软件包中的
大多数类(少数类位于 jre_core 中),以及 java.security.* 、javax.crypto.* 和 javax.security.* 软件包中的类。
如果您关联此账号,则还需要关联 iOS 安全框架。
(请参阅 SDK 库)
|
libjre_sql.a | -l jre_sql |
java.sql 软件包中的
所有类。
|
libjre_ssl.a | -l jre_ssl |
javax.net 和 javax.net.ssl 软件包中的
所有类。
|
libjre_time.a | -l jre_time |
java.time 软件包中的
所有类。
|
libjre_util.a | -l jre_util |
java.util 软件包中的
多个类以及 java.util.logging 软件包。不过,大多数 java.util 类都在 jre_core 中,因此,仅在存在未解析的 JavaUtil* 符号错误(JavaUtilConcurrent* 符号包含在 jre_concurrent 库中)时,才包含此库。
|
libjre_xml.a | -l jre_xml |
XML 相关软件包中的
所有类,包括 javax.xml.* 、org.w3c.dom.* 和 org.xml.sax.* 。
|
libjre_zip.a | -l jre_zip |
java.util.zip 和 java.util.jar 软件包中的
所有类。
如果您关联此渠道,则还需要关联 SDK zip 库。(请参阅 SDK 库)
|
libjre_emul.a (-l jre_emul)
jre_emul
库包含 J2ObjC 的 JRE 模拟中包含的所有类。如果应用已与 jre_emul
关联,则不应包含任何其他 jre_* 库,否则链接器会报告重复符号错误。这是因为 jre_emul
包含这些库中定义的所有类。
其他 J2ObjC 库
以下 Java 库和 Android util 类作为静态库包含在 J2ObjC 发行版中:
媒体库 | 链接标记 | 说明 |
---|---|---|
libguava.a | -l 番石榴 | Guava:适用于 Java 的 Google 核心库 |
libjavax_inject.a | -l javax_inject | JSR-330 依赖项注入注解库。 |
libjson.a | -l JSON | JSON 数据交换库。这是 Android 版本的 JSON,与其他实现略有不同。 |
libjsr305.a | -l jsr305 | 用于软件缺陷检测库的 JSR-305 注释。 |
libjunit.a | -l junit -ObjC | JUnit 测试框架。 |
libmockito.a | -l mockito -ObjC | 适用于 Java 单元测试的 Mockito 模拟框架。 |
libprotobuf_runtime.a | -l protobuf_runtime | 针对 J2ObjC 应用进行了优化的 Google 协议缓冲区运行时。使用 J2ObjC protobuf 的应用应使用 j2objc_protoc 编译其 proto 文件。 |
libandroid_util.a | -l android_util | “android_util”库包含一小部分 Android API 实用程序类。它的目的不是为 Android 环境提供模拟,而只是为了提供一种共享实用类(如“android.util.Log”)的方式。 |
-ObjC 链接标记
-ObjC 标记经常在链接 iOS 应用时使用,但仅在需要从静态库动态加载 Objective C 类和类别时才是必需的。此标志会导致所有链接的静态库中的所有类都包含在应用中,无论它们是否实际使用。因此,当类在运行时未能加载时(一个症状就是抛出 JavaLangClassNotFoundException
),建议使用 J2ObjC 的应用仅在类运行时通过 -ObjC 标志链接。
JUnit 和 Mockito 测试框架在很大程度上依赖于反射,因此使用它们的测试应用应添加 -ObjC 链接。
除了链接到整个静态库中,使一些类可以动态加载,另一种方法是静态引用这些类。在 Java 中,可以在静态初始化程序块中完成此操作;下面是 J2ObjC 的 IosSecurityProvider 类中的一个示例:
// Reference all dynamically loaded classes, so they are linked into apps.
@SuppressWarnings("unused")
private static final Class<?>[] unused = {
IosCertificateFactory.class,
IosMD5MessageDigest.class,
IosRSAKeyFactory.class,
IosRSAKeyPairGenerator.class,
IosRSASignature.class,
IosSecureRandomImpl.class,
IosSHAMessageDigest.class
};