«

与开源社区沟通之实践-有工具也没那么简单!

在平时的开发过程中,尤其是互联网公司里,借助开源的框架、工具或类库是必不可少的,在此真的很钦佩和感谢那些坚守在开源社区的有志之士!但直接的“拿来主义”也是不推荐的,有工具固然是好,用起来却并非那么简单,甚至有时候也存在bug或者不能完全解决你的问题,而需要在它原有的基础上做一些裁剪、定制或增强!

个人觉得如果发现bug或功能不足,首先是自己尝试解决,但最长久和有效的方式还是和开源社区的作者沟通,以求相互改进,如能从代码源头解决你的问题(你的问题也可能是大家的问题),并给开源社区或是开源代码库稍微的添砖加瓦,实是造福更广大人民群众的不二之举!

本篇博文重点介绍在使用ruby开源工具apktools时遇到的问题,以及如何紧急修复,并与开源作者及时沟通,最终得以彻底解决问题的过程!

可以通过如下命令安装apktools开源工具:

    gem install apktools [-v=[version]]

如果是rails开发,可以直接在Gemfile中加上这句:

    gem "apktools", "~> [version]"

遇到问题:试用开始,测试代码如下:

   require 'apktools/apkxml'
    xml = ApkXml.new("apks/netease_cloudmusic_1.6.0.apk")
    manifest_xml = xml.parse_xml("AndroidManifest.xml", true, true)
    puts manifest_xml
拿公司的大多APK测试,发现基本适用,但唯独在解析网易云音乐时会直接报错退出,异常如下:
    ApkResources only supports single package resources.
按照【与开源社区沟通之我见】中沟通前的第一步,应先查看官方文档或`issues`,发现确实有童鞋也遇到相同的问题:

这个是9个月前的提的issue,但作者并未理会……无奈之下,我只好自己看看它的源码如何编写(这就是开源工具的好处啊!)通过源码阅读和搜索,很快就找到了关键代码所在:

    if header_package_count > 1
      puts "ApkResources only supports single package resources."
      exit(1)
    end

和我以及提issue童鞋提到的问题是一致的。而源码并不复杂,于是尝试直接注释掉exit(1)这句,重新运行测试,报错如下:

    in `get_resource_value': undefined method `types' for nil:NilClass (NoMethodError)

再顺藤摸瓜找到它的源代码,问题出现在这一行:

    entry = res_spec.types.entries[res_index]

未对res_spec做nil判断,于是再做稍微修改,在此行代码之前加上如下判断:

    if res_spec == nil
      puts "res_spec is nil" if DEBUG
      return nil
    end

再运行代码,发现APK顺利得以解析,并获得了我想要的信息。 至此,问题从技术上得到了解决,但做rails开发,一般推荐用Gemfile管理和更新你使用的gem库,在作者未修改代码库的前提下,我只能将源码抽取出来,放在lib文件夹下本地加载。这并不是一个好的解决方案,如果作者更新了代码库引入了我需要的内容但还是未修复此问题,我就不得不本地重新下载并修改源码,甚至可能会引入潜在的bug。基于此,我决定给作者再次提issue comment,并fork他的源码,在它源码的基础上做少量修改,给他提pull request,让他重视这件事!

也许是作者被我的真诚所打动((*∩_∩*)),也许是他也觉得不好意思这么久不修复一下,所以马上给了我回复: 看的出来,作者也是想直接修复这个问题,只是找不到很好的Test Case(可见测试很重要,测试用例更重要),希望我能给他提供测试APK文件。接下来的事情就好办了,一路凯歌,知道他修复了这个问题,并发布了新版本,我也不忘表达我的感激之情! 虽然他最终未直接使用我的代码(原作者对代码更熟悉,修复时考虑的更全面),但最终在我蹩脚英文的不屑沟通、简单代码的修改提示以及重要的APK测试用例下,修复了这个关键性问题,我赶脚非常开心!同时也表明,开源社区的人还是很好沟通的!不要吝啬你的想法和意见!

分享