出现的现象
在Android64位的手机上,使用arm64-v8a打包的apk,打开人脸识别瞬间闪退,armabi-v7a没事,很疑惑....
崩溃日志:
java.lang.UnsatisfiedLinkError: No implementation found for void com.sensetime.senseid.sdk.liveness.interactive.d.start()
at com.sensetime.senseid.sdk.liveness.interactive.d.start(Native Method)
at com.sensetime.senseid.sdk.liveness.interactive.InteractiveLivenessApi.init(Unknown Source:13)
at saas.sensetime.liveness.motion.MotionLivenessActivity.onCreate(MotionLivenessActivity.java:340)
at android.app.Activity.performCreate(Activity.java:8592)
at android.app.Activity.performCreate(Activity.java:8565)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1344)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4756)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:5006)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:123)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:3082)
at android.os.Handler.dispatchMessage(Handler.java:117)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:293)
at android.app.ActivityThread.loopProcess(ActivityThread.java:9986)
at android.app.ActivityThread.main(ActivityThread.java:9975)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
或者
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/app/AppCompatActivity;
at android.view.View.performClick(View.java:7729)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1202)
at android.view.View.performClickInternal(View.java:7698)
at android.view.View.access$3700(View.java:886)
at android.view.View$PerformClick.run(View.java:30220)
at android.os.Handler.handleCallback(Handler.java:966)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:293)
at android.app.ActivityThread.loopProcess(ActivityThread.java:9986)
at android.app.ActivityThread.main(ActivityThread.java:9975)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1240)
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.app.AppCompatActivity" on path: DexPathList[[dex file
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:218)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
或者
at android.app.NativeActivity.onCreate(NativeActivity.java:170)
at com.hikvision.frame.view.MvpNativeActivity.onCreate(MvpNativeActivity.kt:25)
at com.hikvision.frame.act.BaseMvpNativeActivity.onCreate(BaseMvpNativeActivity.kt:24)
at com.hikvision.cast.reverse.view.act.ReverseCastActivity.onCreate(ReverseCastActivity.kt:69)
at android.app.Instrumentation.call
ActivityOnCreate(Instrumentation.java:1108)
崩溃直接原因:so没找到
现象分析 libcast.so在启动时就加载且成功了,那说明正常的System.loadLibrary是没问题的 具体是NativeActivity.onCreate()出异常,那肯定是NativeActivity里的实现有问题。 最可疑的地方在:NativeActivity.loadNativeCode(path) 题外话:为什么需要使用NativeActivity? NativeActivity是用C/C++开发Android的方案。在实现反向传屏时,可以直接在C++层采集触控事件,实现反向控制,减少不必要的反射调用(频率还挺高的),降低CPU和延时。
回归正题,继续分析:
看一下loadNativeCode的参数:
mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(), getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()), getAbsolutePath(getExternalFilesDir(null)), Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
先看第一个参数path:
File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
System.mapLibraryName(libname));
if (libraryFile.exists()) {
path = libraryFile.getPath();
}
如果extractNativeLibs为false时,应用的so文件不解压而且页面对齐;如果设置为true时,系统安装服务会把so文件解压到系统目录。extractNativeLibs默认值是true,但是在使用Android Gradle plugin 3.6.0 及以上,没有配置extractNativeLibs时,会把此属性重置为false。
当然还一个隐藏条件,minSdkVersion为23以上。
题外话 android:extractNativeLibs=false:安装时不需要解压,安装速度比较快 android:extractNativeLibs=true:安装变慢,但so会进行压缩,apk大小减小
另外解压后,如果在代码里使用nativeLibraryDir来加载也没问题,像NativeActivity出现的这个问题,本质上其实就是Google的代码写挫了嘛。
举一反三 所以代码里如果有使用到 ActivityInfo.ApplicationInfo.nativeLibraryDir的需要注意版本兼容问题。
原文借鉴 : blog.csdn.net/gab25920hoi…