在新的Android项目中使用.so文件时,是否有必要遵循与so文件相同的包名

时间:2018-03-27 11:01:46

标签: android android-ndk

我使用原生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文件只是隐藏本机代码或者还有其他目的吗?

提前致谢。

2 个答案:

答案 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文件是一个库。因此,目的是方便重用多个项目中实现的功能。