Android JNI System.loadLibrary不需要吗?

时间:2010-08-02 20:52:28

标签: java c++ android java-native-interface

我需要你的帮助才能在Android上添加对JNI的一些见解。我一直在看Android中的/ libcore / x-net包,注意Apache Harmony是SSL功能的默认提供者(使用OpenSSL)。

我在互联网上发现的每个地方都说当你在Android中使用JNI时,你必须使用System.loadLibrary(...)方法加载本机代码,但我无法看到Apache Harmony在哪里使用它所有。我很困惑他们的本机代码是如何加载的。他们的Java代码中没有任何地方可以加载他们的本机库。

/ libcore / x-net / src / main / java / org ... [JNI的Java代码]
/ libcore / x-net / src / main / native /... [JNI的C ++代码]

克里斯

2 个答案:

答案 0 :(得分:5)

Chrisc,

要跟进添加新提供程序,您可以将文件添加到任何所需位置,包括在应用程序中。 Android已经在不同的包中注册了多个提供商。例如,在dalvik / libcore / security / src / main / java / java / security / Security.java

// Register default providers
private static void registerDefaultProviders() {
    secprops.put("security.provider.1", "org.apache.harmony.security.provider.cert.DRLCertFactory");  //$NON-NLS-1$ //$NON-NLS-2$
    secprops.put("security.provider.2", "org.apache.harmony.security.provider.crypto.CryptoProvider");  //$NON-NLS-1$ //$NON-NLS-2$
    secprops.put("security.provider.3", "org.apache.harmony.xnet.provider.jsse.JSSEProvider");  //$NON-NLS-1$ //$NON-NLS-2$
    secprops.put("security.provider.4", "org.bouncycastle.jce.provider.BouncyCastleProvider");  //$NON-NLS-1$ //$NON-NLS-2$
}

并且在libcore / security / src / main / java / java / security / security.properties中也是多余的

但是,即使您将自己的类添加到同一个包中,也不会影响现有的提供程序。这是因为Provider类(例如JSSEProvider)定义了用于提供各种算法实现的类(通过上面看到的属性)

在您的情况下,您可能希望提供新的SSLContext实现。您可以在JSSEProvider中看到它注册SSLContextImpl以提供SSLContext的“TLS”(又称SSL)实现:                  put(“SSLContext.TLS”,SSLContextImpl.class.getName());

因此,您可以添加自己的提供商来注册替代实施。

您无需将您的Provider添加到Security.java或security.properties,但您可以使用Security.addProvider添加新的,甚至Security.insertProviderAt来控制您的Provider按优先级顺序显示的位置。

一旦您注册了自己的提供商,您就可以确保使用SSLContext.getInstance(“SSLContext”,“your-provider-name”)从新提供商处获取实例。或者,如果提供者的优先级高于内置提供者,则所有调用SSLContext.getInstance(“SSLContext”)的程序都将获得新的实现。

另一个注意事项是SSLSocket也可以使用SSLSocketFactory.getDefault()创建。可以覆盖使用自己的SSLSocketFactory和ssl.SocketFactory.provider = org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl(查看SSLSocketFactory.getDefault)。我不确定是否可以在应用程序中完成,不像添加新的提供程序。

最后,就C ++代码而言,您显然可以提供自己的JNI本机代码。如果您只是在应用程序中执行此操作,则您将其注册为任何其他JNI代码(或自动加载),但由于我大部分时间使用内置代码,因此我没有详细说明。与大多数本机代码一样,如果要将代码构建到VM(如当前代码),则需要避免使用符号名称冲突。我们尝试将尽可能多的代码静态作用于文件以避免此类问题。但是,提供不同版本的libssl.so本身完全是另一回事。如果您需要做类似的事情,我没有任何经过测试的设备。

您可能会发现此后续文档对于添加新提供程序的后台也很有用: 如何在Java™加密体系结构中实现提供程序 http://download-llnw.oracle.com/javase/6/docs/technotes/guides/security/crypto/HowToImplAProvider.html

-bri

答案 1 :(得分:3)

% arm-eabi-objdump -p .../symbols/system/lib/libdvm.so
 ...
Dynamic Section:
  NEEDED               libnativehelper.so

% cat dalvik/libnativehelper/Android.mk
 ...
static_libraries := \
    libjavacore \
    libfdlibm

它作为VM二进制文件的一部分自动拉入。本机方法已明确注册 - 请参阅dalvik / libnativehelper / Register.c。

动态加载库可能适用于SSL实现,但是对于许多核心类来说都是有问题的,因为需要实现共享库加载。