Android Workshop线上活动分享
前段时间Google发起的一个Android SDK Workshop 线上活动。因为有问答环节,所以参加了并且准备几个问题要提问,希望得到官方的回答。
1、活动安排
活动日程:(最终安排请以当天日程为准)
10:00 - 10:10 开场
10:10 - 10:30 Android 的最新进展
10:30 - 10:45 ResourcesLoader API 分享
10:45 - 11:15 Google Play 政策介绍
11:15 - 11:45 SDK 开发者与 Google Play 工作方法&资源
11:45 - 12:00 问答
2、问答
准备了几个痛点问题,得到Google开发的解答。
2.1、如何看待API频繁变动
提问1:Android API每年都会有一些改动,新增的特性非常棒,同时可能会deprecate一些API,作为Android开发者就需要一直跟着适配修改。能不能像Java API那样稳定一些?
回答:Google希望能够提供新的API给开发者提供更好的特性,对于过时的API会有一个“黑名单-灰名单-白名单”机制,API文档中被deprecate的API先会被放入灰名单,会在将来某个时间被移除。而直接在黑名单中的API则不再被支持,开发者应该积极适配,这也是开发过程中应该做的环节(代码的重构、适配)。如果开发者希望使用某个非常好用的API,而这个API却被Google deprecate,可以联系Google评估将其放入白名单继续提供支持。
这位Google开发者的回答意思就是不管Google怎么改动,大家都必须要跟着改,错不了。难道各位开发者平时开发的一部分时间不就是需要进行这些适配工作的吗?
2.2、关于createPackageContext()方法的疑问
提问2::问一个技术问题,刚刚讲到ResourcesLoader。想到之前用createPackageContext()方法获取其它应用的Context,从而获取Resources去拿其它应用的资源,这样竟然行得通!可以随意拿别人APK中的资源,这种API会不会在以后被deprecate?
回答:Google之所以提供这样的API是因为Google开发者的理念是所有资源开源共享,Android生态不是封闭的,应用可以通过这种方式跨应用共享一些资源,诸如apk插件化就是用到这种方式。既然APK都能通过反编译等手段直接拿出资源,那么就不应该担心使用这个createPackageContext()方法会暴露重要信息和资源,不应该将重要的用户等信息放在资源中存储。
之所以会问这个问题,是因为之前开发过程中有一个跨应用拿资源数据的需求,一般方法处理棘手,自己阅读源码的时候无意中发现这个方法createPackageContext(),没想到在Context中还有这么厉害的方法,但是有保守开发不赞同用这个方法,认为不安全,或者可能会在以后API 31 32等被废除要重写。
实际上Google的开发者这个回复,给我吃了颗定心丸,Google是不会废除这样的API,因为一直在推进构建Android共享的生态,他们的理念就是资源共享,开源。从该API的官方文档可以看出这是一个安全的方法,对内存影响也极其微小(实测),返回的仅仅是其它应用Context新的轻量级引用,并非真正的重量级ApplicationContext对象,通过该Context可以访问其它应用的资源如:Resources、ClassLoader等。
/**
* Return a new Context object for the given application name. This
* Context is the same as what the named application gets when it is
* launched, containing the same resources and class loader. Each call to
* this method returns a new instance of a Context object; Context objects
* are not shared, however they share common state (Resources, ClassLoader,
* etc) so the Context instance itself is fairly lightweight.
*
* <p>Throws {@link android.content.pm.PackageManager.NameNotFoundException} if there is no
* application with the given package name.
*
* <p>Throws {@link java.lang.SecurityException} if the Context requested
* can not be loaded into the caller's process for security reasons (see
* {@link #CONTEXT_INCLUDE_CODE} for more information}.
*
* @param packageName Name of the application's package.
* @param flags Option flags.
*
* @return A {@link Context} for the application.
*
* @throws SecurityException
* @throws PackageManager.NameNotFoundException if there is no application with
* the given package name.
*/
public abstract Context createPackageContext(String packageName,
@CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
