我使用原生c ++支持创建了一个项目。在这个项目中,我将int值从活动传递给c ++代码,本机代码返回是否为素数。这很好用,现在我想创建.so文件以在另一个项目中使用。我有谷歌很多帖子但没有得到答案如何获得所有设备的不同.so文件。所以我将.apk文件重命名为.zip并将其解压缩。之后我得到一个.so文件。
现在我想在另一个项目中使用这个.so文件。因此我创建了具有不同名称的新项目,但包名称相同。我在src / main中创建了一个目录,并在此lib中将其命名为jniLib,我复制了我的.so文件目录。在我的MainActivity中,我将文件加载为static {
System.loadLibrary("native-lib");
}
并调用我的原生方法private native String isPrimeNumber(int number);
。这里一切都很完美。现在我可以在没有实际c ++代码的情况下获得结果。
现在再次创建新项目并按照上面的步骤创建第二个项目,但区别在于现在我已经更改了应用程序的包名称。当我运行应用程序时,我的应用程序崩溃,错误为
FATAL EXCEPTION: main
Process: com.app.androidkt.differentpackage, PID: 16970
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.app.androidkt.differentpackage.MainActivity.isPrimeNumber(int) (tried Java_com_app_androidkt_differentpackage_MainActivity_isPrimeNumber and Java_com_app_androidkt_differentpackage_MainActivity_isPrimeNumber__I)
at com.app.androidkt.differentpackage.MainActivity.isPrimeNumber(Native Method)
at com.app.androidkt.differentpackage.MainActivity.access$000(MainActivity.java:10)
at com.app.androidkt.differentpackage.MainActivity$1.onClick(MainActivity.java:38)
at android.view.View.performClick(View.java:5268)
at android.view.View$PerformClick.run(View.java:21550)
at android.os.Handler.handleCallback(Handler.java:822)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5811)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:681)
所以我的问题是 - 1)是否有必要使用相同的包名来在我们的应用程序中使用.so文件作为.so文件。 2)我如何得到不同的.so文件目录 - 目前暂时我从apk中提取它。 3)使用.so文件只是隐藏本机代码或者还有其他目的吗?
提前致谢。
答案 0 :(得分:2)
您的应用程序包名称可能是任何内容,但使用libnative-lib.so
中实现的本机方法的Java类必须与此libnative-lib.so
文件的作者完全相同。
设置最简单的解决方法是将 com.app.androidkt.differentpackage.MainActivity 类移至com.app.androidkt.samplendk包。 Android Studio将帮助您进行此重构。请注意,现在您必须在 AndroidManifest.xml 中声明MainActivity的完整路径。
或者,您可以创建一个小的 com.app.androidkt.samplendk.MainActivity class:
package com.app.androidkt.oldpackage;
public class MainActivity {
static {
System.loadLibrary("native-lib");
}
public native String isPrimeNumber(int number);
}
并在 MainActivity.java :
中添加几行package com.app.androidkt.differentpackage;
public class MainActivity extends AppCompatActivity {
private com.app.androidkt.oldpackage.MainActivity pmSolver;
private String isPrimeNumber(int number) {
return pmSolver.isPrimeNumber(number);
}
…
}
如果您不知道用于此libnative-lib.so
的确切包名称,可以通过解析其ELF标题找到它:您将看到一个名为Java_com_app_androidkt_ samplendk_MainActivity_isPrimeNumber
的导出函数。< / p>
Nitpicker的角落:可以构建一个隐藏其指定类名的JNI库,但很难可靠地防止对这些名称进行逆向工程;也可以构建一个可以无缝连接到不同包的JNI库。
答案 1 :(得分:0)
1)是否有必要使用相同的包名来使用我们的.so文件 应用程序如.so文件
不,您可以使用您想要的任何包名称
2)我如何得到不同的.so文件目录 - 目前是时间 因为我从apk中提取了它
将所有.so文件复制到新项目文件夹:src / main / jniLibs / armeabi
3)使用.so文件只是隐藏本机代码或有任何隐藏 还有其他目的吗?
.so文件是一个库。因此,目的是方便重用多个项目中实现的功能。