Android 4.4发布了新的API并为用户和开发者加入了新的特性
我的同事侧重介绍一些大的改动细节,然而我更关注一些细节变化以及开发者在开发过程中可能会遇到的行为改变。
权限
启动快捷键
在API 19中 已经添加了INSTALL_SHORTCUT
和UNINSTALL_SHORTCUT
权限进公布的SDK 。公开这些权限是必要的,它使得应用在设备的加载界面直接添加或删除快捷图标。
这些权限实际上并不是新功能。它们在Android 1.x 的时候就已经被定义好了,在那个时候这些权限是被定义在初始化应用里面而不是公开在SDK, 所以使用了新权限的应用可以获得权限所设定的能力,同时也能运行在老版本的安卓设备上。
外部存储
外部存储的规则改变了。回到4.1,读取外部存储权限被引入作为写外部存储权限的一个补充,而在那个时候并不是必须的。现在,这个权限在4.4中被加强了,但是以一种不同寻常的方式。从访问控制角度来看,外部存储被分成两个主要部分:1、App所在的目录;2、其他地方。
读取或者写入数据到你的App所在的位置,不需要任何权限。这基本可以适用任何通过Context里面的方法可以访问的目录,比如getExternalFilesDir()
或getExternalCacheDir()
。如果只使用这些目录,你甚至可以删除你的应用程序中WRITE_EXTERNAL_STORAGE
权限。
为了读取外部存储上其他数据,应用必须获得READ_EXTERNAL_STAROAGE
或WRITE_EXTERNAL_STORAGE
权限(两者都需要被授权读权限)。这些可以通过Environment获得的目录,比如Environment里面的getExternalStoragePublicDirectory()
或getExternalStorageDirectory()
函数。
更灵活的方法
与系统管理的计时器相关的周期性行为在默认情况下会变得更灵活,比如计时器中的AlarmManager
和SyncAdapter
。这样做的目的是,允许系统尽可能批量处理事件并且减少设备上的唤醒事件以节约电量。
之前的精确方法AlarmManger.set()
和AlarmManger.setRepeating()
,现在的行为更接近于AlarmManger.setInexactRepeating()
并且从属于事件批处理。
从4.4开始,没有任何方法可以创建一个重复的精确闹钟。如果你需要闹钟精确并且可重复,必须调用新的setExact()
方法并且在每个触发事件中设置新的闹钟。
如果你使用SyncAdapter,由ContentResolver.addPeriodicSync()
提供的周期性同步行为在设计上支持一些弹性。这使得在4.4中增加了一个4%同步周期窗口(比如在一个小时的同步周期中占用2.5分钟)。另外,新的SyncRequest.Builder
API已经被允许一次或者有一些控制的弹性周期定期同步。比如SyncRequest.Builder.syncPeriodic()
执行基本的函数,比如addPeriodicSyn()
。可以支持时间间隔,这个时间间隔使得在同步时候适配器可以被优化,变得安全且灵活。
因为这些功能是需要显示设置targetSdkVersion为至少19 ,所以在这个版本之下的并没有这些改变。但是一旦增加了这个版本必须特别注意并且测试你的应用的兼容性。长期来说,尽可能支持灵活时钟和同步将使你的应用尊重设备的电池从而提升整理用户体验。
位图重用
为了更进一步帮助应用程序减少内存占用,android 4.4 建立了重用位图分配的API。简单来说位图分配使得开发者很快达到堆限制。从Android 3.0 开始,使用BitmapFactory解码数据时候就可以重用位图实例(使用 BitmapFactory.Options 中的inBitmap ),但是约束相当的大。图片必须恰好是同样的尺寸和配置,并且只允许JPEG/PNG解码。
在Android 4.4中,我们现在有Bitmap.reconfigure()
去修改和使得现有的实例去适应新的尺寸和像素配置。BitmapFactory 已经被更新,之前在没有这些约束的条件下通过重配置可以重用inBitmap
。
但是约束还是存在的。当位图被创建,它有尺寸大小和配置,其中配置定义了分配的总字节数。对于实例来说这种初始分配大小是不能被改变的。所以当我们多次重配置位图时,每次改变都不可以让需要的字节数超过初始分配大小。
举个例子,可以安全的重配置一个ARGB_8888 200*200
实例为ARGB_8888 100*100
,或者300*300 RGB_565
, 为所有的这些与初始分配相适应。如果试图重配置到ARGB_8888 300*300
,这样会抛出异常。另外一点也很重要,当位图被连接到视图的时候,不能重配置。应该在这个元素被分离或者移出屏幕。
换句话说,如果你的应用程序可确定一个合适大小的单个实例,即使它可能比需要在任何给定时间的像素较大,仍然可以减少内存使用。单个360KB点阵图重用为300×300和200×200的图像(显然不能同时显示),是比两个单独的实例需要520KB(360KB+160KB)更好。
更智能的集合类
为了加入SparseArray
、SparseIntArray
及其他同族行列,Android 4.4引入了一个新的内存高效的集合ArrayMap
。SparseArray
是通过减少必要的分配从而使用原语作为键来提高性能,ArrayMap
允许使用对象全键值映射,但远远比java.util.HashMap
中容量大小更具侵略性,对象分配随着命中率和容量增加而减少。ArrayMap
大小随着个体的删除减少从而保持低内存,一些人们不能从java.util
中的期望。除了作为android.util
在API级别19的一部分;ArrayMap
也在支持库的v19,所以你可以尽情使用,即使你不一定针对4.4。
Immersive模式
Android 4.4引入了一组新的布局标志可用于标记系统UI的可见性。从4.0开始,应用有隐藏状态栏和软导航按钮功能,并暂时使用View.SYSTEM_UI_FLAG_FULLSCREEN
和View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
标志为“精益回”体验,视频内容会占用整个显示屏幕。然而,这种模式不是交互式的,而只要用户点击屏幕上任意位置UI控件立刻返回(你的应用程序没有收到的一个事件)。
为了增强这一点,在Android的4.4添加了View.SYSTEM_UI_FLAG_IMMERSIVE
和View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
。在与所提及的场景中使用这些标志,可以在同一个系统中隐藏用户界面,当与用户的全屏应用程序内容进行交互时候还是保持这种方式。对于让用户无需导航控件,谷歌仍持谨慎态度。但是一个系统级的边缘轻扫手势允许他们在任何时候返回,用户第一次体验这种模式下,系统将叠加出现,迫使确认用户了解如何让UI控件回来。
下面是一个简单的例子,内置一个视图单击处理方法通过需要的标志组合(通过设置android:onClick
属性)使得用户进入Immersive模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
; html-script: false ] public void onToggleClick(View v) { //Hide the system UI. //The system will make the controls re-appear for us //when the user does an edge swipe from the top or bottom. v.setSystemUiVisibility( /* This flag tells Android not to shift * our layout when resizing the window to * hide/show the system elements */ View.SYSTEM_UI_FLAG_LAYOUT_STABLE /* This flag hides the system status bar. If * ACTION_BAR_OVERLAY is requested, it will hide * the ActionBar as well. */ | View.SYSTEM_UI_FLAG_FULLSCREEN /* This flag hides the on-screen controls */ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* This flag tells the controls to stay hidden until * the user brings them back explicitly with a gesture */ | View.SYSTEM_UI_FLAG_IMMERSIVE); } |
之前,我提到的第二标志制作身临其境模式“粘性”。此标志的行为跟第一种方式一样,除了当在任何时候用户回到系统的UI元素的时候,他们会自动隐藏一段时间后而非永久地留放回原处。应用程序可以通过清除粘标志取消此模式。
WebView
在4.4中,WebView也有一些新的改变,现在是完全建立在谷歌的Chromium源代码上。带来的性能改进和来自HTML5和CSS3新功能,但它也意味着有一些行为上的差异需要开发者适应。
capturePicture()
被正式弃用,这是为了支持一个获得WebView内容快照更标准的方法。比如手动触发的onDraw()
可以绘制成位图支持Canvas。
此外,evaluateJavascript()
提供了执行JavaScript的新方法,这新方法支持回调。然而具有同样功能的loadURL()
方法并没有不被鼓励使用或在文档中被弃用。
谷歌提供了一个很好的文档,包含所有可能会遇到迁移到新的WebView的问题细节。
App Ops回归
在4.3初现的App Ops功能现在还没完全准备好。但是有一些已经还是在4.4 SDK中暴露了出来。
现在已经有AppOpsManager
, 这是一个系统服务用于执行应用程序可以沿着它当前的静态权限执行的操作。虽然还不清楚这个API最终将发挥什么作用,但是我们可以看到AppOpsManger
所负责的一些操作类型。每个操作由一个OPSTR_
常量定义,并且在Android4.4中,他们都被用作处理用户位置。
不管我们喜欢还是不喜欢,动态权限执行的模型将会来临。在随后SDK的发展需要密切关注这些元素。
新运行时
自从诞生以来,Android一直依赖虚拟机运行时,即是我们称之为Dalvik,它被用来执行许多应用程序被编译后生成的Java字节码。Dalvik是从自下而上构建的,提供给安卓Java运行时,使得安卓适合于操作系统需要的进程隔离和安全模式。
然而在Android的4.4中,我们可以看到Dalvik的生命周期是有限的,并且将很快由一个完全新的实现被称为Android的运行时(ART)的替换。它还鲜为人知,超过我们收到的介绍范畴。主要的区别似乎是ART将在安装时把Dex字节码编译成本地指令,而不是Dalvik通过使用实时(JIT)编译模型在运行时处理这些。与一些报道相反,似乎没有被任何证据表明这种变化是在全是根据有关Java语言的许可或所有权问题。
ART编译器似乎支持两种模式:快速模式和便携模式。快速模式是类似于JIT(在运行时编译的代码),而便携模式似乎使用LLVM关联预编译。这LLVM的连接可能最终解释的几个版本以前的AOSP的GDK项目神秘现象。
在Nexus 5的设备上,ART被激活从而可以被用来代替Dalvik,这样就允许开发者来测试应用程序和提供有关可能突然出现的新的运行时环境中的任何问题的反馈。所有的开发人员都至少尝试开发启用了ART的应用程序并且报告任何有趣的发现给Google。
这个是我们关于KitKat开发者指南八篇中的一篇,本周晚些时候回来看看新的更新或者关注我们的twitter。