JOOX Music & targetversion25 爬坑指南

导语

随着Android系统的版本更新,现在Android 6.0~8.0的系统占比越来越大,而每一次版本更新Google都会对Android系统做一些涉及到App开发的相关调整。如果我们不主动升级targetversion(后面简称TV)的话,一般来说对于App就不需要进行大的改动,但是当升级TV之后,会导致调用的系统API行为发生更变,从而影响App的使用。 JOOX Music(后面简称JOOX)是腾讯发展海外市场的主要产品之一,目前已发布在6个国家并且成为排名第一的音乐App,JOOX为了能够得到GP的推荐位以加强JOOX的市场地位,需要将TV提高到25,本文主要介绍JOOX是如何从TV 21“爬到”TV 25的。

一、入坑

作为一个刚入职不久的工程狮,某天,我像往常一样起床上班,坐在电脑前开始制造新的BUG,但是,这一天注定是不寻常的一天...

“小X,你过来一下”,leader像往常一样开始召唤我了。

Leader:“交给你一个任务,我们需要将JOOX的TV升级到25。”

我:“没问题,马上搞定。”

修改TV这种事情还用浪费什么时间?palapala直接修改TV到25之后直接RTX leader,“彬哥,任务完美完成,请问还有什么指示?”

Leader沉默了一会:“辞职信写好了吗?”

下一秒拿出我单身20多年的手速迅速撤回并且回了一句“刚刚好像帐号被盗了,自己乱发消息,您继续忙,我还有BUG没写完,就不打扰您了~”。

稳住,开始进入正题啦。在开始接到这个任务的时候,确实是没什么经验,感觉很简单的样子,殊不知自己踩进了天坑里。查了各种资料,总算知道升级TV到25需要注意的地方了:

  • 权限问题

JOOX本身是TV 21,但是Google从Android 6.0开始区分正常权限和危险权限,而危险权限需要App向用户申请授予才能使用,导致App在升级TV到23以上并且在6.0手机上运行时,如果App没有对应的权限然后执行相关操作的话会Crash。这里列出需要动态申请的权限:

具体的可以参考这里:

https://developer.android.google.cn/guide/topics/security/permissions.html?hl=zh-cn#normal-dangerous

  • Doze模式

这个问题不属于升级TV会导致的问题,不过还是提一下。从Android 6.0开始,为了延长电池的使用时间而提供的一个功能,处于该模式时,系统会抑制App的后台任务(例如网络,占用CPU等),只允许部分任务能够正常执行来减少耗电。简单来说就是当系统认为用户没有在使用的时候就会自动进入该模式,不过JOOX目前还没有碰到过相关问题。这里可以参考QQ空间终端团队的文章:

Android M新特性Doze and App Standby模式详解

  • 私有NDK库访问问题

从Android 7.0开始,如果App中有直接访问或者使用的第三方库有使用到私有NDK库的话,对于API 23以上的级别(即TV >= 23)会导致应用Crash,不过低于改级别的运行在7.0系统的手机上也会有相关的弹窗警告。涉及到的库例如libandroid_runtime.so、libcutils.so、libcrypto.so 和 libssl.so等等。

具体可以参考链接中的NDK 应用链接至平台库:

https://developer.android.google.cn/about/versions/nougat/android-7.0-changes.html?hl=zh-cn#ndk

  • 其他问题

上面提到的问题算是比较主要的几个问题。其他问题是解决过程中慢慢发现的,包含有:

①SharedPreferences

②Crypto加密

③调用摄像头

④Android 7.0后查询进程信息

等等相关问题,后面将会列出它们的解决方案...额,可能也没有解决方案...

二、爬坑

上一节列出了差不多大多数App在升级TV时会碰到的问题,这一节就说一下相关的解决方案啦。

  • 权限问题解决方案

权限问题解决方案这里大家可能在看了相关的API之后都感觉没什么问题啦,我也是这样想的...但是,对于JOOX来说就有点蛋疼了。JOOX在Application的初始化中使用到了相关的危险权限,这时候会发现——在Application中不能进行请求权限,而且相关的初始化代码暂时没法搬到Launch的Activity中。

这时候怎么办?当然是“凉拌”呀。

在这里JOOX采用了多进程的方式来获取权限,通过在Application中判断需要用到的权限是否授权,然后启动子进程来获取权限。而为了完善用户体验,这里JOOX通过ps命令来查询进程信息来同步关闭两个进程(像小米提供的长按返回键干掉App,只会干掉主进程,而子进程并没有被干掉...)。然而这样的同步进程状态的方法引出了后面一个大坑...那个坑就在上一节列出了,一会会提到它。

P.S. 在8.0之后系统的权限授权行为已被纠正,在这之前如果你请求并获得了读取存储的权限,系统会错误的将整个权限组的其他权限也授予你使用,也就是说会同时获得写存储的权限。而从8.0开始如果你只申请并获得了读存储的权限,这时候你不会获得写存储的权限,所以你要主动去申请写存储的权限,不过这次申请系统是不会弹窗给用户确认,而是直接授权给你的。

  • Doze模式问题

对于JOOX来说,经过测试之后并没有发现相关的问题影响,所以大家可以参考前面贴的链接来测试和解决自己碰到的问题咯。

  • 私有NDK库访问问题

这个问题的话只能说是简单粗暴了,要不然不要使用私有库,要不然将用到的私有库放到你的jni库的路径下打包也行,第三方库的话应该都会有对应的更新。麻烦的地方在于如何找出哪里用到了,可以通过写一个测试类将所有库都加载一遍...不过比较麻烦,也可以通过如下命令:

aarch64-linux-android-readelf -dW libMyLibrary.so

工具在ndk目录下的

toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin

目录...反正我这边是在这里,你也可以通过查找找一下看看...

  • SharedPreferences

对于SP,主要是设置flags的问题,Android 4.2之后Google就不推荐使用MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE两个标志位了,TV大于23并且是7.0的系统的话会直接抛出异常,由于JOOX以前使用的是这两个,导致在提升TV之后直接Crash,改成MODE_PRIVATE就可以了。

  • Crypto加密问题

在Android 7.0后废弃Crypto加密方式,具体可以查看:

https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html

如果一定要用它的话可以通过如下方式兼容:

https://stackoverflow.com/questions/39097099/security-crypto-provider-deprecated-in-android-n/42337802#42337802

  • 查询其他进程信息问题

摄像头调用的话就不提了,网上都是解决方案。这里说一下查询进程信息...这就是前面说到的大坑(好吧,对于JOOX来说)。

这天,当我将前面提到的问题都解决了之后,提交代码。当晚正准备提测,为了确认DTS音效在升级之后是否正常,卸掉App之后重装,结果一运行就Crash了...Crash了(┬_┬)。然后自己手动打开权限后就可以正常运行,初步确认问题出在权限获取子进程上。这里贴一下Crash之后的log...

这...什么gui?谁知道问题出在哪?最主要的是,debug包能够正常运行,而release包不行...经过不断反复的查看打印的log之后,发现了一条重要的线索:

为什么说是重要的线索?因为代码里面有调用到启动Home的逻辑。

P.S. 由于在没有权限的时候会kill掉主进程来退出App,但是App会被系统重新拉起来,因为系统会拉起被强杀的应用Activity栈中栈顶的Activity,所以先启动Home的话再kill掉就不会被自动拉起了。这里也提示大家在完全退出App的时候如果使用到kill,exit这些方法的话先将所有Activity干掉,防止App被系统自动拉起。

继续上面的分析,由于当JOOX的子进程根据包名查询主进程的存活情况的时候失败了,导致应用一启动就直接执行了退出的代码...因为在7.0之后,Google限制了进程相关信息的访问权限,仅能够获取本身进程的信息了(这回是真的)...所以通过ps命令或者访问相关文件都不能够获取到其他进程的信息了,不过debug包可以访问到同一个App的所有进程,release包访问不到,导致在爬这个坑的时候——非常蛋疼!这也是目前没办法解决的问题。更多了解可以看一下这篇文章:

https://jaredrummler.com/2017/09/13/android-processes/

三、总结

文章提到的问题都是一点一点慢慢爬出来的,虽然说网上的适配文章很多,但是大部分内容都是相同的,当遇到一些比较偏的问题只能说是自己慢慢爬了,写这篇文章也是为了方便大家爬坑。

从前面的问题可以看出Google对于Android生态隐私相关方面的控制越来越严格了,从禁止各种访问就可以看出来,未来估计还会继续限制一些私有内容的访问,对于用户来说是件好事,但是对于开发者(我)来说...还愣着干嘛?赶紧去写个BUG压压惊。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

IBG JOOX的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT大咖说

VMware vSphere 6.7 新功能介绍

内容来源:2018 年 06 月 19 日,VMware大中华区原厂高级技术讲师姚泉在“VMware在线技术专题分享·第二期”进行《VMware vSphere...

1443
来自专栏Android 研究

反插件化:你的应用不是一个插件(转)

Android插件化技术是应用程序级别的一项创新型技术,它的初衷主要是用于热更新,减少APK安装包的大小,以及解决65535方法数量的限制。从技术层面来说,An...

762
来自专栏FreeBuf

记我的一次账号劫持和BLIND XSS漏洞发现过程

我发现的第一个漏洞就是不安全对象引用漏洞(IDOR),利用该漏洞我能在每个账户中创建一个 element x元素,经过和朋友的交流,他建议我可以试试在其中注入一...

960
来自专栏技术分享

聊下git pull --rebase

有一种场景是经常发生的。 大家都基于develop拉出分支进行并行开发,这里的分支可能是多到数十个。然后彼此在进行自己的逻辑编写,时间可能需要几天或者几周。在这...

1907
来自专栏云瓣

关于 Node.js 的认证方面的教程(很可能)是有误的

原文地址:Your Node.js authentication tutorial is (probably) wrong 我搜索了大量关于 Node.js/E...

2839
来自专栏james大数据架构

如何开发自己的搜索帝国之安装ik分词器

   Elasticsearch默认提供的分词器,会把每个汉字分开,而不是我们想要的根据关键词来分词,我是中国人 不能简单的分成一个个字,我们更希望 “中国人”...

2145
来自专栏FreeBuf

Android木马分析简介

本文介绍基于Android的手机恶意软件,是一个基础性的介绍,给新入门的人提供一个分析和工具指引。要分析的木马是一个2013年的syssecApp.apk,这个...

1839
来自专栏阮一峰的网络日志

编译器的工作过程

源码要运行,必须先转成二进制的机器码。这是编译器的任务。 比如,下面这段源码(假定文件名叫做test.c)。 #include <stdio.h> int m...

2976
来自专栏杨建荣的学习笔记

使用sysbench压力测试MySQL(一)(r11笔记第3天)

今天用了下新版本的sysbench,发现和早期版本的差别还不小,确实有不少有趣的地方,是的,我们继续测试下MySQL。 如果大家看过《高性能MyS...

3768
来自专栏运维技术迷

openwrt将LAN口改为WAN方法

牢骚 折腾了好几个好几个小时,终于搞好了。原因就是因为固件里面的端口序号和实际路由器后面的序号不一致,导致我的设置和物理连接对不上,这是个巨坑。 折腾需求 PS...

3565

扫码关注云+社区