在Android应用程序中使用现有的共享库(.so)。

 2023-01-19    360  

问题描述

我有以下方案要处理.我得到了一个共享库(libeffect.so),用于在我为客户工作的Android项目中使用.我没有共享库源代码,我只有.so文件.图书馆已预先编译以在Android设备上工作.与共享库一起,我有方法签名

public static native void doEffect(int param1, IntBuffer intBuffer);

所以现在我有一些关于如何调用此本机方法的Questiosn,如果可能只有.so文件,那么它们就有:

在Android应用程序中使用现有的共享库(.so)。

  1. 我需要将本机方法签名放在与.so所定义的相同软件包/类中能够在共享库中找到该方法?例如,如果此共享库首先在类mypackage.myclass中使用,我是否需要创建相同的软件包,然后将方法签名放在那里?

  2. 我需要在哪里将此.SO文件放入我的Eclipse Android项目中,以将此文件部署在我的APK文件中?

这些问题听起来可能是菜鸟,但是我以前从未与JNDI合作过,所以如果可以在没有任何错误的情况下调用方法效果,我有点担心.任何可以指导我的答案都是非常欢迎的.

非常感谢
Thiago

推荐答案

  1. 我需要将本机方法签名放在与
    那些定义的是.so是或我
    可以在任何中使用此签名
    我项目中的包装/班级
    在运行时,JVM将能够
    在共享库中找到方法?
    例如,如果此共享库
    首先在课堂上使用
    mypackage.myclass,我需要创建
    同一包,上课,然后放
    那里的方法签名?

无需创建相同的软件包/类.您可以将方法签名放在任何软件包中.

public class NativeLib {

  static {
    System.loadLibrary("so_file");
  }

  public static native void doEffect(int param1, IntBuffer intBuffer);
}

2.我需要在何处将此.so文件放在我的日食android项目中
要将此文件部署在我的APK文件中?

您已将此.SO文件放在应用程序的LIB文件夹中.如果没有LIB文件夹,则可以创建一个LIB文件夹并放置.SO文件.您可以使用 system.loadlibrary(” so_ file”);

调用它

其他推荐答案

1我需要将本机方法签名放在同一
套件/类是.SO或我可以使用的时定义的套件
在我项目中的任何包装/类中的签名,在运行时
JVM将能够在共享库中找到该方法?

根据 http://docss. oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html 您必须使用匹配的软件包和类名称.

我只观察到JNI方法,其中C侧函数称为JAVA_COM_COMPANY_WHATEWATES_SOMECLASS_SOMEMETHOD,这意味着您必须将”本地”声明放入类似命名的Java类中.

使用工具’nm’或’nm ++'(它们在NDK中的预编译文件夹中)查看.so文件,并查看所定义的功能.如果您看到任何起始Java_,那是您想要的.

我对前面的说法表示怀疑,即您可以调用Java_package_class_method格式中未命名的函数;如果确实有效,这可能是一种旧的行为,但是即使可以的话,这似乎很危险 – 您可能会遇到错误的行为.

2我需要在哪里放置此.SO文件在我的日食中
将该文件部署在我的APK文件中的项目?

您的.So居住在libs/armeabi,libs/armeabi-v7a,libs/x86和/或libs/mips/mips/mips/mips,具体取决于您正在使用多少平台,” libs”是” src’的同伴”和” res”.我不知道Android是否在Libs/没有平台预选赛中看起来很明显,但没有明显的好处.大多数/所有英特尔设备(包括精美技术)使他们能够在X86硬件上执行大多数ARM库.

,这种情况有些复杂.

此外,我喜欢声明JNI类的界面并提供工厂(这里是简洁的方法,但我更喜欢工厂类),如果出错了,它可以提供接口的无操作实现:促进单元测试,并且还避免在调用方法之前必须弄乱测试null值(假设您舒适地认为已发货库将永远不会缺少或更改方法签名 – 您的集成测试应检查一下):

):

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();
}

我通常不称界面为’xxxi’,但我假设您的图书馆的JNI类并不称为诸如Utilityjni之类的好东西(anupon我称之为界面’效用’).

以上所述是小编给大家介绍的在Android应用程序中使用现有的共享库(.so)。,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25837.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。