Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 907|回复: 0

android 视频录制 混淆打包 之native层 异常的解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-9-4 15:36:27 | 显示全部楼层 |阅读模式

    原文地址:http://www.cnblogs.com/linguanh/    (滑至文章末,直接看解决方法)

    问题起因:

      前5天,因为项目里面有个类似 仿微信 视频录制的功能, 先是上网找了个 开源项目:https://github.com/qdrzwd/VideoRecorder,下载下来,在 debug 非混淆的模式下 测试了几次,觉得效果还不错,便在它的基础上进行了 二次开发。

      于当天晚上整合好项目,准备第一次的混淆打包(release模式),然后第一次测试,结果,我意料中的事情发生了,没错,就是在混淆后经常发生的各种 蹦,对于这类问题,不吹不黑,我经验算是丰富的了,一般都是在 proguard-rules 文件(android studio) 下做混淆设置解决的,但我不得不承认,这个是我迄今遇到最棘手的,直到 15:46 才正式解决,怎么说都 4 天了,百度上没有直接的解决信息,逐择文以告之。

    前序:

      先说说这个开源项目的背景吧,它是基于 Vine 的背景下进行开发的,Vine 是外国的一个做短视频分享起家的公司,也是他们 APP 的名字,后被Twitter收购,目前网上的录制视频都是基于android自带的MediaRecorder类,但是这个类比较鸡肋,实话实说,用处不是很大,用来练习下还是可以的。Vine  录制视频使用javacv自带的api, 录制声音使用的是android的AudioRecord,同样,这个开源项目也是基于 二者 开发的。这里顺便说下,微信用的库,微信和微视一样,用的是自己编译的 ffmpeg库,vine使用的是javacv库。看到这里,你是不是在想,我是怎么知道的?其实很简单,去网上下载这几个 APP,反编译下,看看 libs 下的 .so 就知道了。

      网上查资料后发现javacv已经提供了视频录制功能,并且包含有视频编辑等图像处理功能。在javacv的开源项目链接可以下载它:https://code.google.com/p/javacv/  

    具体问题:

      好了,前面吹了这么多,先说下我遇到的奇葩问题先。

      

    从下往上看,到最后提示的是 加载动态链接库 libjniPointer.so 出问题了,这是一处比较重要的信息,还有两处分别是  javacpp.loader.loadLibrary  、 nativeLibraryDirectories=[/data/app/cn.itguy.recordvideodemo-1/lib/arm, /vendor/lib, /system/lib]] ,它们告诉了我三点, 这个问题是加载 linux 下的动态库失败,找不到了,由jar包里面的loader类中的loadLibrary函数触发,最终找不到的位置是手机系统的的lib库,system、vendor。

      是不是有种想去手机system/lib 里面看看有没有 jniPointer.so 的冲动?事实不用去看,我前面说过在 debug 下是没问题的,也就证明了这个库必然存在,找不到是因为混淆的原因。

    通常的做法:

      因为这类问题是库找不到,一般我们回去自己项目里面的 .so 文件夹中找找有木有,这是一种盲目的做法,首先应该看错误信息,例如上面的,找不到的路径的 system/lib 也就和本地项目文件夹无关,事实也是这样,libjniPointer.so 这个东东,原来项目里面就是没有的。

      然后就是混淆配置文件--proguard-rules:具体的所有操作,网上有很详细的例子,我这里不废话,直接针对我遇到的情况开刀

      首先点开用到的jar包    为了保证 里面的包不被混编,我们会使用   -keep 和 -dontwarn,然后再补上一句不混淆 native方法->,依赖注入不混淆->,还不放心的话,可以狠点再次指出属性和方法都不混淆->,看到这里,我们会想,应该行了,一般是行的,可能有同志会指出要保护下 .so 啊,-libraryjars libs/xxx.so 这样子,其实不用,.so 默认不混淆的,所有上面的做法,一般来说,是行的,但是,对于这个视频录制来说,还不行。

     

    真正解决

      在执行了上面的设置后,如果还不行的话,基本上再百度也没什么用了,因为百度上面没有,等我发完这篇文章估计就有了。

      再回到问题的根源, 它是加载由jar包里面的loader类中的loadLibrary函数触发,最终找不到的位置是手机系统的的lib库,system、vendor 下的jniPointer.so,我们怎么办啊?看源码,还是得这样的,下面我贴出我的查找路径,所有代码是 这个 视频录制 开源项目、javacpp 里面的:

    首先打 log 跟踪到->,在new AVPacket() 里面抛出异常,我们点进去->,因为allocate()没有其他操作,我们可以跳过它,在此类里查找 static 静态块,它先于构造函数执行->->->->,看到loadLibrary了-> 最终getRunTime,整条线索对应 异常信息,到了这里,这里是系统的 system 类,当 libName = “libjnipointer” 的时候,找不到了。  推测,是系统的某些资源被混淆了。我们的混淆配置中有一句设置:-keepattributes 保护给定的可选属性,那么我们可以用它保护下项目的注释、资源文件、资源目录名、内部类等,例如这样:,事实证明,当我添加到 InnerClasses 的时候,问题解决。

     

    解决方法:

      在混淆文件中添加  保护下项目的注释、资源文件、资源目录名、内部类(主要的解决项)

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-3 07:28 , Processed in 0.103251 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表