Android Q Labs| 现代化您的应用

这里说的现代化并非说利用Android新版本里面那些,因此今天主要讲的是主要三个方面:chrome

1.非 SDK 接口限制在安卓 Q 里面的一些演进,但愿开发者们移除对非SDK接口的限制;缓存

2.六十四位的应用,就是但愿你们可以尽快地提供你的应用的六十四位版本;安全

3.targetSdkVersion,就是你们把本身的应用的 targetSdkVersion 提高到比较新的系统版本号 。架构

接口限制

咱们知道实际上是在去年 Android P 的时候,在 ndroid九的时候引入了非 SDK 接口的限制,咱们的目的是为了帮助开发者只使用公开的接口来完成全部的功能,才得到在未来的 Android 版本中更好的一个兼容性,进一步的提高用户体验,同时也可以下降开发者的维护成本。

非 SDK 接口影响应用兼容性

而后做为基本原则,咱们是从开发者不多使用的那些非SDK接口来入手,开始实施限制,而且经过应用 targetSdkVersion 来区分限制的程度,给开发者更长的时间来进行适配。同时咱们也对开发者一些合理的需求增长一些新的公开结构支持,就说把这些相关的接口放入公开的 sdk 当中,从而全面的引导开发者一除对非 SDK 接口的依赖。ide

基本原则

这里是Android P版本的时候的限制名单,它基本上分为黑名单,深灰名单和浅灰名单。而白名单就是SDK自己就是你们全部的应用都是能够随意调用的那些API。

而后咱们在 Android Q 里面这个名单有了必定的演进,就是他的黑名单、浅灰名单和白名单的含义是跟以前相同的。工具

可是深灰名单被分类成两个,一个是至关因而从P的那边带过来的,咱们叫作针对P的社会名单,也就是说当你的targetSdkVersion到了P或者P以上的时候,这里的接口就不可使用了,他们就等同于黑名单。而后还有多出来一块叫作针对Android Q的社会名单,就说当应用到targetSdkVersion到了Android Q或者Android Q以上的时候,就等同于黑名单。 性能

而后这边是具体的限制名单的类型和它们各自的含义。
通常来讲,若是你的应用是在一个较低的targetSdkVersion上面,而后从Android P到Android Q的时候若是你没有一些其余的第三方应用的依赖,通常来讲不会遇到限制名单的限制,但当你的应用升级到targetSdkVersion到P的时候,就会受到Android P的深灰名单的限制,当升级targetSdkVersion到Android Q的时候,就会受到Android Q的深灰名单的限制,而后在代码级别为了区分出这些身份名单的种类,因此咱们新增了一个叫作UnsupporteAppUsage这么一个注解,全部带有注解的接口就处于就表明它处于限制名单中,而后这个注解又能够包含一个叫作maxTargetSdk的参数,而后用来指定特定的targetSdkVersion对接口的访问。

好比说当有一个接口,它上面的注解,就只含有UnsupporteAppUsage注解,可是不含有maxTargetSdk参数的时候就表示这个接口是处于浅灰名单中。若是maxTargetSdk参数为零,或者说其实整个这一行都是一个opinion的,就是说若是没有注解的私有的API,或者是带有这么一行,就是maxTargetSdk参数为零的这行注解的话,那么就说明这个接口是属于黑名单当中。若是maxTargetSdk参数好比说是Android P的时候,那就说明这个接口是处在应用了TargetSdk模型到P或者Android P如下的时候是能够访问的,可是在Q的时候就禁止访问。 测试

下面这个文档在咱们的开发者网站上就详细介绍了Android Q中非sdk接口的更新的信息。

从右边的菜单里面可以看到有一个有一块是从灰名单到移入黑名单里面的接口列表,并且咱们不但就是列出了全部从会名单移移到黑名单里的接口,并且每一个接口后面就有个红色的那些注释,都会告诉开发者说你应该转而使用另外一个公开的接口。下面还有一个是从灰名单移入白名单中的接口列表。因此若是你的应用在Android P中使用的一个接口,如今被移到了好比说黑名单当中,那么若是对你来讲是一个很是强烈的需求,并且你以为是个合理的需求的话,那么你能够经过文档里有一个连接阐明理由,能够去申请一个公开接口,这个连接会把你直接带到咱们的公开的Buganizer里面,这等因而你直接对Android的产品团队发了一个bug。优化

同时在国内其实咱们知道,由于市场上Android生态的一些碎片化,因此国内的应用常常会使用加固或者是插件化热修复这样的方案。这方案每每使用了不少的非sdK接口,创成为应用在新的Android平台上一个不兼容的一个主要缘由,因此其实咱们也跟加固和热修复的厂商作了很是多的合做,了解他们需求。而后咱们了解到有两个比较常见的需求,一个就是加固之后的应用,在运行的时候,首先要对那种加密的代码在内存中进行解密,而后经过InMemoryDexClassLoader来进行加载。 而后对于插件化或者热修,他们常常会用父ClassLoader来加载补丁之后的类用原来的那个子ClassLoader来加载未补丁的类。因此在安卓Q里面对这些自定义的加载器和加载逻辑,咱们也提供了一些新的接口和优化,来帮助解决国内就是加固和热修复的一些兼容性的问题.

在安卓Q里面咱们新增了一个新的公开接口,就是APPComponentFactor.instantiateClassLoader能够帮助加固和热修方案,在应用启动的时候就插入到一个进程的建立过程中,在运行其余代码以前就建立而且设置本身的一个自定义的主ClassLoader。
咱们还对InMemoryDexClassLoader进行了优化,以前,若是好比说对加固它内存中解压的那些代码,若是用InMemoryDexClassLoader去加载的时候,就是说每次使用,每次加载都会有都会进行一个一验证。而后这个是很是耗时的,因此咱们如今Android Q里面InMemoryDexClassLoader,他会缓存加载类的验证信息,因此下次你再启动应用去夹在同一个累的时候,就会直接跳过耗时的验证过程,可以帮助应用去下降加载时间,提升运行的效率和用户的体验。

而后再对于开发者来讲,测试你的应用的方法有好几种,好比说第一种能够去编译本身应用的一个targetSdkVersion到Android Q的一个可DebugBal可调试的版本,而后在Android Q的设备或者模拟器中去运行,第二种你也能够在应用中稍微修改一下代码,调用StrictMode API detectNonSDKAPIUsage()而后去注册一个penaltyListener()。这样的话,若是你的应用在运行的过程当中调用了非SDK接口的话,那么就会收到一个叫onVmViolation的一个回调,再次回到里面会有个Violation的参数,你能够在回调中去实现一些本身的自定义的逻辑,好比说记录下来call stick来方便你更精确的定位问题。

那么前两种是那种动态的检测方法,就是很是精确,可是它可能覆盖率不是很高,他须要去依赖你到底跑了哪些测试的test case。因此咱们也提供了一个叫作Veridex的一个静态检测工具(此工具是开源的,在AOSP里面直接有它的源代码,咱们也提供了各个平台的预编译版本,而且在每一个Android Q的Beta发布的时候,都会对VS工具进行更新)。用这个工具你能够只运行一条命令,就去检测你的APK文件,而后它就会扫描出来全部APK文件里可能会用到非SDK接口,可是固然由于它是个静态检测工具,因此它有一些局限性,好比说它不能侦测JNI的调用,而后它对反射调用的诊测也可能不是百分之百准确,他有可能好比说当你在用很复杂的字符串的操做去拼接出来一个你要反射的接口的时候就不知道拼接出来最后的结果接口大概什么样子的,或者说你有一个虽然是反射调用代码级别,看起来是反射调用,可是其实这是一段死代码,那么它仍是会曝出来讲,你这里可能在调用非SDK接口,但其实在你的应用中,由于它是快时代,因此不可能被调用到,因此说虽然他有这些局限,可是由于它是静态检测,因此它的检测效率很高,你也不须要test case,因此它可以它可以提供更多的代码覆盖率,因此你们能够去结合这种动态检测的静静态检测来去看一下本身的应用到底使用哪些非SK接口。网站

对测试来讲,咱们提供了好几种方法来让你们在Android Q上进行测试,第一个是模拟器,就是你用最新的Android studio最新的3.5beta版本,里面会带有就是Android Q版本的模拟器。还有就是咱们会提供Android Q beta的Pixel系统印象,你们能够直接若是有Pixel手机的话,能够直接刷机。咱们也跟不少的OEM合做,提供了一些OEM的OEM支持的Android beta的设备,也就是说你们能够在咱们的开发者网站中找到这些设备列表,而后每一个设备它都会连接到提供商的一个网页,就是教你怎么样去把设备刷到Android,Android Q应该是Beta3的版本。 最后咱们也在Android Q上提供了常规系统映像GSI,这是咱们一个project trouble的一个一个进展,也就说是理论上来讲,只要是发布的时候搭载安卓P的手机,那么他应该全面支持拆包的。在Q以后咱们会持续的引进Sdk接口限制,咱们会建立与新的maxTargetSdk相关的社会名单,把一些非SK接口移到更加合适的限制名单,而后会根据开发者的需求去增长新的公开的接口支持,而且会发布更多的技术文档。
在Android Q以后咱们会持续的引进Sdk接口限制,咱们会建立与新的maxTargetSdk相关的社会名单,把一些非SK接口移到更加合适的限制名单,而后会根据开发者的需求去增长新的公开的接口支持,而且会发布更多的技术文档。
下一个是六四位的应用。
首先咱们必须认可,六十四位构建可能会让你的APK体积变得稍微大一些,但它一般会让你的应用或者游戏运行的更快,由于六十四位指定机支持更高的代码和运营效率,好比说它能使用两倍数量的计程器,而后它能支持双精度的浮点运算,这使得编译器能够作更复杂的是量化的优化。
更好的消息若是你的应用是在Googleplay上发布的话,那么你可使用APP Bundle做为发布的格式。若是这样的话,用户下载你的应用的时候,他收到的APK的包体积也不会受到太大的影响。由于Googleplay会按照用户设备的架构来仅向他推送他所须要的文件,就好比说你的APP Bundle里包含了32位和六四位两套so的文件,那么根据用户设备的架构类型,googleplay只会向她推送其中的一套架构文件,一样获得一样的道理,你也能够构建一个包含X86和F86-645年的bundle,这样的话你不须要去担忧他们对目标为arm的设备的应用体系影响,也就是说你的应用实际上是还支持可以在chrome os上面去跑的话,那么你提供这两套文件也是很是有帮助的。

如今六四位已经成为googleplay的一个政策,咱们在2017年末的时候就向开发者传达了这个要求。到了今年8月份的时候,全部在google平台上上家的新应用和已有应用的更新都必须包含六十四位版本。可是这里有个例外,就是最后一个时间点,2021年8月,这是由于咱们知道还有不少游戏在使用Unity5.6或者更高版,或者更低版本的游戏引擎来开发的。

对于这样的游戏,咱们专门有个特例,就是说在googlepla上还能够继续基于这些32位的unity更新两年的时间。 而后到2021年8月开始,就是google play就不会再向任何兼容流思惟的设备去推送非六十四位的应用和游戏了。其实到那个时候有可能就是咱们甚至都不能保证说安卓设备仍然可以运行32游戏,就由于有可能那个时候有不少的主流设备就变成是仅支持六十四位的架构了。而后对于使用unity引擎的话就的游戏来讲,若是你要升级到六十四位,那么你必须使用2017.4.16或者是2018.2或者之后的unity引擎版本。
那么对于开发流速应用来讲,总的来讲就是四个步骤,第一请使用安卓studio里面的APKAI者就APK分析器来去查看你的应用。 里面全部的32位的依赖,你能够在lib文件夹中看一下,就是X86和armeabi-v7a甚至更早的V5这些目录,这些目录里包含的so就是三十二位的。而后接下来你须要进行一个六十四位构建。
固然在代码级别你可能还要作一些事情,保证全部的颜色代码都可以在六十四位的环境中进行正确的运行,好比说最基本的就是你的代码中不能假设指针类型的固定大小。
而后你也应该把你的应用中所使用的SDK和依赖库都升级到六四为的新版本。若是他们尚未六十四位版本的话,那么你须要去督促他的提供商去解决,或者说你用的是开源的库的话,你本身去把它去built到六十四位。
最后固然不能忘了测试,当你作出来一个六四位版本的应用以后,你能够在本地进行测试,而后或者是你可使用Googleplay的测试发布通道。
最后咱们再说一下targetSdkVersion的升级。
咱们知道targetSdkVersion模型其实就是一个整数,每一次安卓一个主版本的时候,它所对应的系统的等级都会提升,其实对应用来讲,你设置一个targetSdkVersion,就是告诉系统说个人应用已经对R级别的API进行了兼容性的测试和改,而后系统应该尽可能保持对等级的行为的一个兼容性。但这只是一个尽可能保持新的系统并不会保证说百分之百去兼容旧版本旧的API上的行为。这里咱们也知道targetSdkVersion其实跟应用所运行的系统的版本是没有关系的。
不少开发者认为其实targetSdkVersion可能只是去会影响系统API的一些行为,但其实它的影响还会更深远一些。好比说在SELinux中,底层的文件系统,它可能会根据应用的targetSdkVersion去设置文件的标签,而且去产生一些沙盒性逻辑就好比说当你targetSdkVersion到了28或者以上的时候,那么他们的文件是不能够与其余的其余的应用来直接共享的,你须要经过content provider来进行分享。
那么为何要升级targetSdkVersion有如下几个方面。
这里是一年多以前的googleplay应用市场。 那个时候是没有targetSdkVersion的限制的,因此说开发者能够自由选择本身想使用的targetSdkVersion。这会咱们就会发现,其实整个应用的targetSdkVersion是很是碎片化的,不少应用会故意去选择一些比较低的targetSdkVersion。它的问题就是对用户来讲体验会不一致,而后用户买了一个新的手机上面运行的是一个比较新的安卓的系统,可是他在使用一些旧的应用的时候,并无得到新系统所提供的一些性能和安全性上的收益。而后最后咱们还发现不少的应用,他们故意保持在一个比较低的targetSdkVersion上来,作他们一些很差的事情。

因此说从2017年末的时候,咱们go派就发布了一个新的政策,主体的思想就是说全部在Googleplay上商家的应用,他们的targetSdkVersion必须是一年以内发布的安卓安卓的主版本号。也就是好比说咱们在2017年8月份发布了安卓O那么这里就会要求在2018年8月份,全部新应用的targetSdkVersion要达到26。对于已有应用,咱们给了三个月的宽限期,全部已有应用的升级版本,他们的targetSKversion要在2017年11月份以前达到安卓O的版本26。 而后在今年5月份的时候,google play的开发者的后台也增长了检查逻辑。从5月份开始,若是你上传应用的时候targetSdkVersion没有达到26,他就会给你一个警报,但从8月份开始就会直接拒绝。
这里是如今的GooglePlay市场上的应用的targetSdkVersion分布,这里就看到碎片化获得了根本性的改善。这边基本上几个新的版本在三分天下。
咱们今年继续更新了GooglPlay的targetSdkVersion政策,其实整体思想和方向跟以前是彻底保持一致的,也就是说咱们去年8月份发布了安卓P targetSdkVersion是28,那么从今年的8月份开始全部的新应用,在GooglePlay上商家的时候,他的targetSdkVersion必定要38或者以上。而后11月份全部已有应用的更新版的targetSdkVersion的必定要是28或者以上。
那么在购物市场以外怎么办?其实咱们也作了不少的努力。首先咱们要看到的是这些恶意软件各异的应用,他们的targetSdkVersion每每都是比较低的,好比说是21或者19。
咱们也很高兴地看到,一些第三方的市场,好比说中国主流的OEM和一些第三方市场都签署了一个高等级APA的一个公约。
在安卓的系统的层面,咱们会增长一些GooglePlay Protect的警报。就是说若是你在新的安卓的手机上去安装一个应用的话,那么无论你从哪里安装,只要你的手机是支持GooglePlay Protect的话,protect也会经过也会作相似的检查,当你新安装的应用targetSdkVersion比较低的时候,它就会发出一个这样的警报。

而后咱们也知道有些应用其实并非用户安装的,多是有些设备上预安装了不少应用,那么对于这这种状况咱们得有一个新的GMS的要求。
还有一个就是权限复核,咱们知道在好比说在targetSdkVersion小于23的时候是不支持动态的权限申请的,因此说对于这样对于这些targetSdkVersion比较低的应用安卓在安装在安卓Q上面之后第一次运行的时候,那么它会弹出来一个这样的权限复合的一个界面,很是明确的告诉用户说应用须要用哪些权限,这时候用户能够去看一下而且作出调整,就是去解除掉一些权限。这也只是在第一次运行的时候会出来一次。
最后对于targetSdkVersion实在很是低的应用,咱们会有一个运行时警告。 这个是在安卓P的时候引入的,在安卓P的时候,若是用户去运行一个targetSdkVersion小于17的应用,那么在每次运行的时候都会有这个警报。在安卓Q里面这个被调高了23,当应用targetSdkVersion小于23的时候,每次运行的时候都会有警告,而后这边会有一个检查更新,若是可以支持ACTION_SHOW_APP_INFO的话,它会把你带到一个应用市场去看有没有新版的应用可供下载。
因此今天大概就跟你们介绍这三个问题,但愿开发者们回去检查你使用了哪些非SDK接口,尽可能的去转而使用一些公开的SDK,而后尽快的提供出一套六十四位的版本,最后尽可能把你的应用的targetSdkVersion升级到更高的版本。