1我需要放置机方法签名在同 包/班那些定义的时候。因此,或者我可以在我的项目中的任何程序包/类中使用此 签名,因此在运行时期间,jvm将能够在共享库中找到该方法?
根据http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html,您必须使用匹配的包和类名称。
我只观察到JNI方法,其中C端函数被称为诸如Java_com_company_whatever_SomeClass_someMethod之类的东西,这意味着您必须将“本机”声明放入类似名称的Java类中。
使用工具“nm”或“nm ++”(它们位于NDK中的预编译文件夹中)查看.so文件并查看其中定义的函数的调用。如果你看到任何启动的Java_,那就是你想要的。
我对前面的声明持怀疑态度,您可以调用未在Java_PACKAGE_CLASS_METHOD格式中命名的函数;如果它真的有效,它可能是一种遗留行为,但即使可以,它看起来也很危险 - 你可能会得到错误的结果。
2我在哪里需要将这个.so文件放在我的eclipse android 项目中以便将此文件部署到我的apk文件中?
你。所以住在库/取决于你有多少与平台,其中“库”是一个对工作armeabi,库/ armeabi-V7A,库/ X86,和/或库/ MIPS 'src'和'res'。我不知道Android是否在libs /没有平台限定符的情况下查找,但没有明显的好处。大多数/所有英特尔设备的情况稍微复杂一些,包括花哨的技术,允许他们在x86硬件上执行大多数ARM库。另外,我喜欢声明一个JNI类的接口并提供一个工厂(这里是一个简洁的方法,但我更喜欢一个工厂类),如果事情出错,它会提供一个无操作接口的实现:它便于进行单元测试,并且避免在调用其方法之前必须混淆空值的测试(假定您感到满意,您发布的库永远不会丢失或更改方法签名 - 您的集成测试应该检查它):
public interface YourLibI {
@Override
public native yourMethod();
public static final NO_OP = new YourLibI() {
@Override
public void yourMethod(){}
}
}
public class YourLib extends YourLibI {
public newYourLibI() {
try {
return new YourLib();
}
catch (UnsatisfiedLinkError e) {
Log.e("YourLibJNI", "Load failed, returning NO-OP dummy", e);
return YourLibI.NO_OP;
}
}
static {
System.loadLibrary("arbitronSDK");
}
private YourLib() {
}
@Override
public native void yourMethod();
}
我通常不会调用接口'xxx',但我假设您的库的JNI类不像UtilityJNI那样被调用(因此我会调用接口'Utility')。
谢谢@Sujit。我在看这个教程,http://www.android10.org/index.php/articlesother/276-call-c-code-from-application-using-ndk,我看到生成的C++代码片段有方法名由java包和方法名组成。这不会影响我使用本地签名的方式吗?我希望我应该遵循共享库创建时使用的相同名称约定。另一个问题,一旦我在我的AndroidProject/lib文件夹中有.so文件,这个文件将与APK文件一起导出吗?我是否需要创建子文件夹armeabi文件夹?非常感谢,T – Thiago