Xamarin Android Java绑定库运行时访问本机库失败

Xamarin Android Java绑定库运行时访问本机库失败,xamarin,xamarin.android,java-native-interface,Xamarin,Xamarin.android,Java Native Interface,TL;DR:我正在寻找一种方法,从运行特定于供应商的定制Android构建的Android设备中查找并提取本机共享库(.so)文件。我需要这个文件作为Xamarin.Android Java绑定库中缺失的部分 我正在尝试为Java SDK创建一个Xamarin.Android绑定库,该SDK在Famoco的Android设备上公开激光条形码扫描API。这些设备运行特定于供应商的Android构建,该构建支持一些特殊功能,例如集中式设备管理 我按照命令创建绑定库,没有使用任何自定义转换或添加,也没

TL;DR:我正在寻找一种方法,从运行特定于供应商的定制Android构建的Android设备中查找并提取本机共享库(.so)文件。我需要这个文件作为Xamarin.Android Java绑定库中缺失的部分

我正在尝试为Java SDK创建一个Xamarin.Android绑定库,该SDK在Famoco的Android设备上公开激光条形码扫描API。这些设备运行特定于供应商的Android构建,该构建支持一些特殊功能,例如集中式设备管理

我按照命令创建绑定库,没有使用任何自定义转换或添加,也没有编译器错误

以下是绑定库中生成的factory方法,该方法尝试创建新的
BarCodeReader
实例:

[Register ("open", "(ILandroid/content/Context;)Lcom/zebra/adc/decoder/BarCodeReader;", "")]
public static unsafe global::Com.Zebra.Adc.Decoder.BarCodeReader Open (int readerId, global::Android.Content.Context context)
{
    const string __id = "open.(ILandroid/content/Context;)Lcom/zebra/adc/decoder/BarCodeReader;";
    try {
        JniArgumentValue* __args = stackalloc JniArgumentValue [2];
        __args [0] = new JniArgumentValue (readerId);
        __args [1] = new JniArgumentValue ((context == null) ? IntPtr.Zero : ((global::Java.Lang.Object) context).Handle);
        var __rm = _members.StaticMethods.InvokeObjectMethod (__id, __args);
        return global::Java.Lang.Object.GetObject<global::Com.Zebra.Adc.Decoder.BarCodeReader> (__rm.Handle, JniHandleOwnership.TransferLocalRef);
    } finally {
    }
}
引发异常:
未找到void com.zebra.adc.decoder.barcodereder.native_安装程序(java.lang.Object,int,java.lang.Object)的实现

我从中了解到,这种类型的故障通常是由于无法解析所需的本机库而导致的

为了确认原因,我使用JD-GUI对Famoco JAR进行了反编译,从中提取了以下实现代码片段:

// This is the underlying Java implementation of the above bindings library factory method
public static BarCodeReader open(int readerId, Context context)
{
    return new BarCodeReader(readerId, context);
}

// This is the BarCodeReader constructor that is called by the factory method
BarCodeReader(int readerId, Context context)
{
    this.mEventHandler = null;
    this.mAutoFocusCallback = null;
    this.mDecodeCallback = null;
    this.mErrorCallback = null;
    this.mPreviewCallback = null;
    this.mSnapshotCallback = null;
    this.mVideoCallback = null;
    this.mZoomListener = null;

    Looper aLooper = Looper.myLooper();
    if (null == aLooper) {
        aLooper = Looper.getMainLooper();
    }
    if (aLooper != null) {
        this.mEventHandler = new EventHandler(this, aLooper);
    }
    native_setup(new WeakReference(this), readerId, context);
}

// This method is called by the above constructor, but fails because no implementation exists
private final native void native_setup(Object paramObject, int paramInt);
在我看来,出现上述运行时错误是因为私有方法
native\u setup
不是在Java代码中实现的,而是在绑定库项目中没有引用的本机库中单独实现的。这似乎是一个合理的诊断吗

不幸的是,我在Famoco提供的SDK工具包中没有找到任何.so(本机库)文件。我已经联系了他们的支持团队,他们表示在使用他们的SDK JAR时不需要链接.so文件。Famoco并不热衷于在他们的设备上支持跨平台应用,但他们确实确认他们有其他客户使用Xamarin,他们似乎已经解决了这个问题。不幸的是,Famoco的支持人员似乎无法告诉我如何实现这一点

是否设备上已经存在所需的本机库(作为自定义Android构建的一部分部署)?为了验证这一假设,我安装了Famoco sample laser scanning应用程序,该应用程序运行正常,尽管其项目源代码工具包中没有.so文件的迹象


如果是这样,从Android环境中查找和提取.so文件是否可行?我应该如何执行此操作?

是的,应在自定义设备上预安装libbarcoderereader44.so文件。它可以位于/system/lib或/vendor/lib目录中。在调用
open()
方法之前,必须从代码中加载此库。您可以找到Famoco SDK的更多详细信息。

非常感谢!一个很好的答案完全解决了我的问题。
// This is the underlying Java implementation of the above bindings library factory method
public static BarCodeReader open(int readerId, Context context)
{
    return new BarCodeReader(readerId, context);
}

// This is the BarCodeReader constructor that is called by the factory method
BarCodeReader(int readerId, Context context)
{
    this.mEventHandler = null;
    this.mAutoFocusCallback = null;
    this.mDecodeCallback = null;
    this.mErrorCallback = null;
    this.mPreviewCallback = null;
    this.mSnapshotCallback = null;
    this.mVideoCallback = null;
    this.mZoomListener = null;

    Looper aLooper = Looper.myLooper();
    if (null == aLooper) {
        aLooper = Looper.getMainLooper();
    }
    if (aLooper != null) {
        this.mEventHandler = new EventHandler(this, aLooper);
    }
    native_setup(new WeakReference(this), readerId, context);
}

// This method is called by the above constructor, but fails because no implementation exists
private final native void native_setup(Object paramObject, int paramInt);