从tensorflow加载android项目中的.so文件时出错

时间:2018-05-25 09:36:01

标签: android tensorflow gradle

我想为我的android项目添加tensorflow支持(从演示中我自己的对象检测版本),并且不想处理bazelcmake来构建本机库tensorflow使用的。因此,正如在tensorflow GitHub项目中发布的许多问题所推荐的那样,我从Jenkins下载了最新的成功夜间版本,其中包含一个apk文件,用于测试对象检测演示和.jar文件以及来自不同架构的.so文件。

所以我将预构建的库libtensorflow_demo.solibtensorflow_inference.so (arm64-v8a,armeabi-v7a,x86,x86_64)libandroid_tensorflow_inference_java.jar文件添加到了我的库中libs目录。

我将这些行添加到我的gradle中:

lintOptions {
    abortOnError false
}

sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

在我的proguard-rules-pro中我添加了这个:

-keepclasseswithmembers class * {
    native <methods>;
}

使用以下方式加载 .so

 System.loadLibrary("tensorflow_demo");

我解压缩 .apk 以检查它是否存在,并且它就在那里。

从我的logcat

我发现了这个:

I/TensorFlowInferenceInterface: Checking to see if TensorFlow native methods are already loaded
I/TensorFlowInferenceInterface: TensorFlow native methods not found, attempting to load via tensorflow_inference
I/TensorFlowInferenceInterface: Successfully loaded TensorFlow native methods (RunStats error may be ignored)
I/TensorFlowInferenceInterface: Model load took 123ms, TensorFlow version: 1.8.0-rc1
I/TensorFlowInferenceInterface: Successfully loaded model from 'file:///android_asset/frozen_inference_graph_stripped.pb'

但是当应用程序启动它崩溃并抛出此错误时:

java.lang.UnsatisfiedLinkError: No implementation found for void com.example.aboussaada.myapplication.tracking.ObjectTracker.initNative(int, int, boolean) (tried Java_com_example_aboussaada_myapplication_tracking_ObjectTracker_initNative and Java_com_example_aboussaada_myapplication_tracking_ObjectTracker_initNative__IIZ)
    at com.example.aboussaada.myapplication.tracking.ObjectTracker.initNative(Native Method)
    at com.example.aboussaada.myapplication.tracking.ObjectTracker.init(ObjectTracker.java:261)
    at com.example.aboussaada.myapplication.tracking.ObjectTracker.getInstance(ObjectTracker.java:224)
    at com.example.aboussaada.myapplication.tracking.MultiBoxTracker.onFrame(MultiBoxTracker.java:219)
    at com.example.aboussaada.myapplication.DetectorActivity.processImage(DetectorActivity.java:215)
    at com.example.aboussaada.myapplication.camera.CameraActivity.onPreviewFrame(CameraActivity.java:155)
    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1153)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

那么我在这里做错了什么?非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

正如所建议的那样,将.so文件下载并包含在您自己的项目中是不够的。由于我们包含了库的预编译版本,因此本机方法(在.cpp文件中)的名称上包含tensorflow demo的包名称。这就是为什么发生此错误的原因,因为我们自己的项目包命名不同。

  • 要解决此问题,您需要将包重命名为org.tensorflow.demo,并确保ObjectTracker.java位于org.tensorflow.demo.tracking下。

  • 第二种解决方案是改变本机方法的命名 根据您的包名称在.cpp文件中,然后重建 带有bazel的.so文件(如果有人管理,那里面临很多问题) 要做到这一点,请提及如何)。

  • 我希望tensorflow团队在建议下载和删除pre-buit版本时会提及这些信息,以便那些经验不足的开发人员不会在这个问题上浪费不必要的时间。