在Release中没有找到void com.organ.app.Activity.a()的实现。

问题描述 投票:0回答:1

我想做的是简单地从我的Java android活动中调用一个在我的C++代码库中实现的本地函数。签名可以是任何东西,但我们把它定义为 void fooBar().

我的工作空间是由gradle项目组成的树形结构,除了app是 "com.android.application "之外,其他都是 "com.android.library "项目。所有的项目都包含了某种形式的C++代码,还有一些包含了Java类。活动类在根项目("Core")中。函数的本地实现在同一个项目的.cpp文件中。

这是logcat的错误输出。

E/com.organization.app: No implementation found for void com.organization.app.Activity.a() (tried Java_com_organization_app_Activity_a and Java_com_organization_app_Activity_a__)
E/AndroidRuntime: FATAL EXCEPTION: Thread-9
    Process: com.organization.app, PID: 3607
    java.lang.UnsatisfiedLinkError: No implementation found for void com.organization.app.Activity.a() (tried Java_com_organization_app_Activity_a and Java_com_organization_app_Activity_a__)
        at com.organization.app.Activity.a(Native Method)
        at com.organization.app.Activity.onStart(Unknown Source:0)

当我在为Debug构建时,我可以调用这个。fooBar() 函数没有问题,但在Release中,它试图使用不同的名称加载函数。也就是: a(). 本地端的函数签名没有问题,因为如果我简单地将函数名称改为 Java_com_organization_app_Activity_a我还试着添加了更多的函数,这些函数的新名字变成了----------。b()c(),分别是。

似乎我在哪里调用函数并不重要,所以事实上它说的是 onStart 这里是无趣的。

我试着搜索有类似问题的人,但都是CC++中函数签名的问题。

java android c++ java-native-interface
1个回答
1
投票

我找到了解决方案。

我在Debug和Release之间做了一些交叉引用,发现要么关闭了 minifyEnabled 或删除proguard文件声明,使得异常消失了。之后,我查看了我使用的proguard文件(恰好是优化的默认文件),看到了两个有趣的部分。

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
    native <methods>;
}

^ 这个部分应该是确保我的原生函数没有被从二进制中丢弃。为什么会发生这种情况,我仍然不知道。

# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep

^ 这一节让我想到了使用 @Keep 来强制它不丢弃该函数。经过一番测试和确认,事实证明这是一个有效的解决方案。

我会进一步做一些测试,找到收缩器不保留我的原生函数的根本原因,但既然找到了解决方法,我就标记为已解决。希望对以后遇到的人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.