我需要将条形码扫描仪的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
我做了什么:
我下载了.jar
文件的SDK,并放入了app/libs
我在the build.gradle
中添加了这一行以获取SDK的路径
dependencies {
...
implementation fileTree(include: ['*.jar'], dir: 'libs')
}
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);
}
}
}
react-native
端: ...
componentDidMount() {
// Access the function created in the java module
NativeModules.CodeBarre.initScanner((err ,name) => {
console.log(err, name);
});
}
应用文件夹中的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'
}
答案 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,对吗?
问题是,他们的SDK适用于THEIR设备。 C库是其中的一部分。我猜您是在用非famoco设备进行测试,还是有人只是假设SDK可以正常工作就向您发送了SDK,但除非他们将C文件或famoco设备发送给您,否则它将不会。实际上,Famoco的测试项目指出:
/ ** *此应用程序在FX300上测试条形码扫描仪。 *它依赖于包含以下共享库的图像: *系统/库/ * /
队友,您得到了答案。要么获得Famoco FX300,要么放弃sdk。
答案 1 :(得分:0)
从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
。
// 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.
}