程序员

2019-03-25 使用dlopen动态加载JNI库失败,提示

2019-03-25  本文已影响4人  HaloMartin

问题描述:

如题,Android项目中使用了FFmpeg封装成的JNI文件libffmpeg.so,在Google API 23之前,该错误还只是一个警告,并不影响使用,加上上一位工程师不在意和疏忽,没有在编译的时候添加-fPIC来去掉此警告,最近,因为Google的一些隐私政策更新,导致需要更新App,由于新App被要求compileSdkVersion必须在API 26以上,导致此问题变得突出,因为在API 23后,该警告被升级为错误,并引起崩溃,崩溃的堆栈信息如下:

2019-03-25 11:58:42.053 10374-10913/? E/AndroidRuntime: FATAL EXCEPTION: Thread-40
    Process: com.hhws.singapore, PID: 10374
    java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/com.hhws.singapore-p5l_BGv3e_OO-QO2VPlwGQ==/lib/arm/libffmpeg.so" has text relocations
        at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
        at java.lang.System.loadLibrary(System.java:1660)
        at com.ffmpeg.H264Decode.<clinit>(H264Decode.java:43)
        at com.ffmpeg.H264Decode.Initlization(Native Method)
        at com.hhws.lib360.video.PlaySurfaceView.videoDecode(PlaySurfaceView.java:223)
        at com.hhws.lib360.video.PlaySurfaceView.access$000(PlaySurfaceView.java:52)
        at com.hhws.lib360.video.PlaySurfaceView$1.run(PlaySurfaceView.java:517)

环境:

Window 7:
Android Studio 3.3.2
minSdkVersion=19
compileSdkVersion=26
buildToolsVersion=27.0.3

Mac OS 10.14.3
Android Studio 3.3.2
minSdkVersion=19
compileSdkVersion=26
buildToolsVersion=27.0.3

方法尝试:

1. 重新编译

寻找libffmpeg.so的源码,尝试进行重新编译
失败,持有源码的员工离职太久,并且不是很配合,暂时不考虑请求他帮助

2.编译官方FFmpeg

因为libffmpeg.so的库文件名与官方的名字一样,尝试下载官方版本重新编译后接入
失败,生成官方版本的libffmpeg.so后尝试替换,提示没有发现对应方法实现:

2019-03-25 10:31:53.774 7325-8452/? E/AndroidRuntime: FATAL EXCEPTION: Thread-76
    Process: com.hhws.singapore, PID: 7325
    java.lang.UnsatisfiedLinkError: No implementation found for long com.ffmpeg.H264Decode.Initlization() (tried Java_com_ffmpeg_H264Decode_Initlization and Java_com_ffmpeg_H264Decode_Initlization__)
        at com.ffmpeg.H264Decode.Initlization(Native Method)
        at com.hhws.lib360.video.PlaySurfaceView.videoDecode(PlaySurfaceView.java:223)
        at com.hhws.lib360.video.PlaySurfaceView.access$000(PlaySurfaceView.java:52)
        at com.hhws.lib360.video.PlaySurfaceView$1.run(PlaySurfaceView.java:517)

在命令窗口使用nm -D libffmpeg.so > nmlibffmpeg.txt对比旧的JNI库和官方方法生成的libffmpeg.so文件的符号表:

0001d641 T Java_com_ffmpeg_H264Decode_DecodeH264Frame
0001d4f9 T Java_com_ffmpeg_H264Decode_Destory
0001d4b9 T Java_com_ffmpeg_H264Decode_GetHeight
0001d521 T Java_com_ffmpeg_H264Decode_GetPixels
0001d499 T Java_com_ffmpeg_H264Decode_GetWidth
0001d6d1 T Java_com_ffmpeg_H264Decode_GetYUVPixels
0001d761 T Java_com_ffmpeg_H264Decode_Initlization
0001d4e5 T Java_com_ffmpeg_isKeyFrame

可发现上一名员工修改了FFmpeg官方的代码添加了这8个方法,并且自己做了优化,使Java调用时不需要包含ffmpeg的头文件信息,但是该工程师没有交代好这个ffmpeg库的源码信息,导致现在无法进行重新编译以修复问题。

3.以FFmpeg的官方方法适配目前项目的需求(还未实践)

项目中使用的主要是音视频的编解码功能,应该有相关参考的资料,可以尝试的方向

4.向该部分JNI制作者请教

这个就比较尴尬了~而且不知道会不会被要求收费,相当尴尬

上一篇下一篇

猜你喜欢

热点阅读