无法将Android第三方扫描仪库加载到我的本机应用程序中

时间:2019-04-02 10:23:24

标签: android react-native

我需要将条形码扫描仪的SDK集成到我的react-native应用程序中,但仍然出现错误:

Couldn't load XXX from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.mobile-1.apk"],nativeLibraryDirectories=[/data/aoo-lib/com.mobile-1, /system/lib]]]: findLibrary returned null

我做了什么:

  1. 我下载了.jar文件的SDK,并放入了app/libs

  2. 我在the build.gradle中添加了这一行以获取SDK的路径

dependencies {
  ...
  implementation fileTree(include: ['*.jar'], dir: 'libs')
}
  1. 我创建了native module以便能够加载SDK

这是我在CodeBarre.java中的本机模块代码:

package com.myApp;


import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;


import java.util.Map;
import java.util.HashMap;
import android.util.Log;

import com.zebra.adc.decoder.BarCodeReader; // that's the scanner SDK

public class CodeBarre extends ReactContextBaseJavaModule {

public CodeBarre(ReactApplicationContext reactContext) {
  super(reactContext);

}

private static final String TAG = "BarcodeSdkDemo";


@Override
public String getName() {
  return "CodeBarre";
}

// here's how i'm trying to load the SDK
@ReactMethod
public void initScanner(Callback cb) {
  try {
      System.loadLibrary("IAL");
      System.loadLibrary("SDL");
      System.loadLibrary("barcodereader44"); // Android 4.4
      Log.i(TAG, "Barcode scanner drivers loaded");
      cb.invoke("Barcode scanner drivers loaded");
  } catch (Exception e) {
      Log.e(TAG, "error static initialization  block", e);
      cb.invoke(e.toString(), null);
  }
 }
}
  1. react-native端:
  ...
  componentDidMount() {
    // Access the function created in the java module
    NativeModules.CodeBarre.initScanner((err ,name) => {
      console.log(err, name);
    });
  }
  1. 这是我得到的错误: enter image description here

  2. 这是我放在/ app / libs中的.jar文件: enter image description here enter image description here

  3. 应用文件夹中的build.gradle

    apply plugin: "com.android.application"
    
    import com.android.build.OutputFile
    
    project.ext.react = [
      entryFile: "index.js"
    ]
    
    apply from: "../../node_modules/react-native/react.gradle"
    
    android {
      compileSdkVersion rootProject.ext.compileSdkVersion
      buildToolsVersion rootProject.ext.buildToolsVersion
    
      defaultConfig {
         applicationId "com.mobile"
         minSdkVersion rootProject.ext.minSdkVersion
         targetSdkVersion rootProject.ext.targetSdkVersion
         versionCode 4
         versionName "0.1"
      }
    
      signingConfigs {
        release {
          if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
              storeFile file(MYAPP_RELEASE_STORE_FILE)
              storePassword MYAPP_RELEASE_STORE_PASSWORD
              keyAlias MYAPP_RELEASE_KEY_ALIAS
              keyPassword MYAPP_RELEASE_KEY_PASSWORD
             }
          }
         }
         splits {
          abi {
           reset()
           enable enableSeparateBuildPerCPUArchitecture
           universalApk false  // If true, also generate a universal APK
           include "armeabi-v7a", "x86", "arm64-v8a"
         }
        }
    
        buildTypes {
          release {
             minifyEnabled enableProguardInReleaseBuilds
             proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
             signingConfig signingConfigs.release
           }
          }
          // applicationVariants are e.g. debug, release
             applicationVariants.all { variant ->
             variant.outputs.each { output ->
          // For each separate APK per architecture, set a unique version code as described here:
          // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
          def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3]
          def abi = output.getFilter(OutputFile.ABI)
          if (abi != null) {  // null for the universal-debug, universal-release variants
              output.versionCodeOverride =
                    versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
         }
        }
      }
     }
    
        dependencies {
         implementation project(':react-native-device-info')
         implementation project(':react-native-vector-icons')
         implementation fileTree(dir: "libs", include: ["*.jar"])
         implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
         implementation "com.facebook.react:react-native:+"  // From node_modules
        }
    
        // Run this once to be able to run the application with BUCK
        // puts all compile dependencies into folder libs for BUCK to use
         task copyDownloadableDepsToLibs(type: Copy) {
           from configurations.compile
           into 'libs'
         }
    
  4. 以下是如何加载SDK的说明: enter image description here

2 个答案:

答案 0 :(得分:2)

专业提示:在寻求与依赖相关的问题的帮助时,总是会包含您的成绩文件。

该消息表示您的应用无法找到本地库。在android世界中,这意味着C库,而不是java库。在android世界中,您拥有:

-Java库:JAR文件。与Java世界中的其他地方几乎一样。

-Android库:AAR文件。压缩文件的结构不仅公开JVM字节码,而且还公开相关的XML文件(如清单文件),并根据gradle插件版本公开.so文件。

-本机库:SO文件。将由您的代码调用的C程序。

您得到的文件是常规jar。如您所见,它不包含所需的.so文件(“ IAL”,“ SDL”,“ barcodereader44”)。如果SDK提供程序给您一个jar文件,他们还必须给您提供一组上述.so文件。您需要将它们包括在构建中。以下答案显示了如何手动执行此操作: How to include *.so library in Android Studio?

如果缺少.so文件,请向SDK提供程序询问。它们可能看起来像这样:

https://github.com/LeiHuangZ/ScanServiceNew/tree/master/se4710/src/main/jniLibs/arm64-v8a

请记住,每种处理器体系结构都需要不同的.so文件集。

编辑:基于SDK的软件包名称,我猜他们还没有发送给您的文件就是这个文件:https://github.com/LeiHuangZ/ScanServiceNew/blob/master/se4710/src/main/jniLibs/jniLibs.rar

在等待他们回答时,请尝试使用这些答案。请记住,他们未提供x86版本,因此仅针对arm和armv7调整apk拆分。

编辑:

Google缓存是您的朋友。您正在使用Famoco的SDK,对吗?

https://webcache.googleusercontent.com/search?q=cache:iJQugfLm27wJ:https://help.famoco.com/developers/sample-code/fx300-imager/+&cd=2&hl=en&ct=clnk&gl=us

问题是,他们的SDK适用于THEIR设备。 C库是其中的一部分。我猜您是在用非famoco设备进行测试,还是有人只是假设SDK可以正常工作就向您发送了SDK,但除非他们将C文件或famoco设备发送给您,否则它将不会。实际上,Famoco的测试项目指出:

/ **  *此应用程序在FX300上测试条形码扫描仪。  *它依赖于包含以下共享库的图像:  *系统/库/  * /

队友,您得到了答案。要么获得Famoco FX300,要么放弃sdk。

答案 1 :(得分:0)

解决方案

  1. 整理包裹。

从Android将本机模块添加到React Native时,您需要按以下方式注册您的模块。

// CustomToastPackage.java

package com.your-app-name;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CustomToastPackage implements ReactPackage {

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  @Override
  public List<NativeModule> createNativeModules(
                              ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();

    modules.add(new ToastModule(reactContext));

    return modules;
  }

}

如果您未注册该模块,它将返回null

  1. 在MainApplication.java中初始化模块
// MainApplication.java

...
import com.your-app-name.CustomToastPackage; // <-- Add this line with your package name.
...

protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new CustomToastPackage()); // <-- Add this line with your package name.
}

Official