一直在用fir.im作为测试APP分发,最近遇到了上传失败的问题,看看到底是什么原因导致的。
fir(<1.7.0) 上传报错,且无法正确获取APP姓名和icon等
fir(>=1.7.0) 上传正常,但无法正确获取APP姓名和icon等
fir(1.7.0以下) 上传报错,日志如下
fir p /Users/Jenkins/Home/workspace/Android/Prod/app/build/outputs/apk/Release/app-release.apk -T tokentokentokentokentokentoken -Q
undefined method `attributes' for nil:NilClass
/Library/Ruby/Gems/2.3.0/gems/ruby_android-0.7.7/lib/android/manifest.rb:222:in `label'
/Library/Ruby/Gems/2.3.0/gems/ruby_android-0.7.7/lib/android/apk.rb:176:in `label'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/util/parser/apk.rb:27:in `basic_info'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/util/parser/apk.rb:17:in `full_info'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/util/info.rb:34:in `apk_info'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/util/publish.rb:13:in `publish'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/cli.rb:118:in `publish'
/Library/Ruby/Gems/2.3.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
/Library/Ruby/Gems/2.3.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/cli.rb:183:in `invoke_command'
/Library/Ruby/Gems/2.3.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
/Library/Ruby/Gems/2.3.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/bin/fir:8:in `<top (required)>'
查看源码
https://github.com/FIRHQ/fir-cli
/Library/Ruby/Gems/2.3.0/gems/fir-cli-1.6.12/lib/fir/util/parser/apk.rb:27:in `basic_info'
fir官方处理办法:rescue捕获错误,不抛出异常
这样但导致应用名称,icon等信息获取不到,解决办法并不完美,有没有更好的解决办法呢?
//fir
//## 更新记录
// - (1.7.0) 过期了ipa_build 功能, 增加了对 android manifest instant run 的兼容
def fetch_label
@apk.label
rescue NoMethodError
nil
end
有没有更好的办法,继续挖
fir-cli引用了ruby_android-0.7.7库
查看源码
ruby_apk
/Library/Ruby/Gems/2.3.0/gems/ruby_android-0.7.7/lib/android/manifest.rb:222:in `label'
通过代码定位attributes
def label(lang=nil)
label = @doc.elements['/manifest/application'].attributes['label']
...
end
@doc.elements['/manifest/application'] 为nil
看到这里,就需要清除manifest文件结构了,
参考https://bbs.pediy.com/thread-194206.htm
还要了解下Big Endian 和 Little Endian
参考https://blog.csdn.net/sunshine1314/article/details/2309655
定位到https://github.com/SecureBrain/ruby_apk/blob/master/lib/android/axml_parser.rb
通过解析文件数据,发现
//通常的结构如下
TAG_START_DOC
TAG_START
TAG_START
TAG_END
TAG_START
TAG_END
TAG_END
TAG_END_DOC
出问题的apk解析如下
TAG_START
TAG_START
TAG_END
TAG_START_DOC
TAG_START
TAG_END
TAG_END_DOC
TAG_START
TAG_END
...
TAG_END_DOC
此处出现了多个TAG_END_DOC
再来看源码,当遇到TAG_END_DOC就break终止了遍历,导致文件解析终止,也就无法解析到label等信息了。
尝试注释掉break,果然信息就可以正常解析了。
代码如下
https://github.com/sparkrico/ruby_apk
...
when TAG_END
@parents.pop
when TAG_END_DOC
//break
when TAG_TEXT
...
虽然解决了问题,但仍有不解之处,为何这个apk包有多个TAG_END_DOC?等下一篇找到这个答案
参考资料
Ruby String#unpack