>这次把这两个主题放在一起写下。虽然 **Java 8**出来已经有很长一段时间了,而 **Android M**还只有几周时间,但是前者的很多特性也许很多 Android 程序员都不了解或是没有使用过,所以姑且都算新东西了。
再插一句:作为程序员去了解自己所专研平台或语言的 最新趋势 是很重要的,所以也为我这么晚才去关注 Java 8的新特性而感到一点惭愧(囧)。
J8允许为接口提供一个默认的实现方法,只用在方法前加上 default
关键字即可将其作为完整的方法实现:
interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); } }
第二个方法 sqrt()
即为默认方法, 任何实现了该接口的类都可以直接继承此方法并调用。
首先可以看一下 Lamda表达式百度百科的介绍 ,简单说来 Lambda表达式 就是一个匿名函数,可以用于简化代码,在许多语言中都有它的实现(比如 Python、C#)。
Java 8中终于支持了 Lambda表达式 也算是很大的进步,因为这个改进带来的影响是显而易见的。提到 匿名函数 ,就很容易想到 匿名内部类 ,这就是 Lambda表达式 可以应用的一个场景。
EG:
// 1.1使用匿名内部类 new Thread(new Runnable() { @Override public void run() { System.out.println("Hello world !"); } }).start(); // 1.2使用 lambda expression new Thread(() -> System.out.println("Hello world !")).start(); // 2.1使用匿名内部类 Runnable race1 = new Runnable() { @Override public void run() { System.out.println("Hello world !"); } }; // 2.2使用 lambda expression Runnable race2 = () -> System.out.println("Hello world !");
当然其实这也只能算是一个语法糖,给人的感觉牛逼一点。事实上Android Studio 中很早就开始把写好的匿名内部类优化成 Lambda表达式 来简化代码了。
Lambda表达式基本格式:
(参数/空)->表达式与返回值
// 1. 不需要参数,返回值为 5 () -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值 (x, y) -> x – y // 4. 接收2个int型整数,返回他们的和 (int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) (String s) -> System.out.print(s)
有关这个话题我暂时不谈,因为自己对函数式也没多少了解(囧)。还是等我也学一门函数式语言之后再回来填这个坑。
可以看一下这几个链接:
浅谈Java 8的函数式编程
Java函数式编程教程
Java 8中支持多重注解了,先看个例子来理解一下是什么意思。首先定义一个包装类Hints注解用来放置一组具体的Hint注解:
@interface Hints { Hint[] value(); } @Repeatable(Hints.class) @interface Hint { String value(); }
Java 8允许我们把 同一个类型的注解使用多次 ,只需要给该注解标注一下 @Repeatable
即可。
@Hints({@Hint("hint1"), @Hint("hint2")}) class Person {}
@Hint("hint1") @Hint("hint2") class Person {}
这也算是支持函数式编程所引入的一个功能,现在我们可以把 方法作为参数 来传递了。
Java 8 允许使用 ::
关键字来传递 方法或者构造函数引用 ,下面的代码展示了如何引用一个静态方法和一个对象的方法:
Converter<String, Integer> converter = Integer::valueOf; Integer converted = converter.convert("123"); System.out.println(converted); // 123 converter = something::startsWith; String converted = converter.convert("Java"); System.out.println(converted); // "J"
这里的 Converter
是一个 函数式接口 ,在声明时需要加上 @FunctionalInterface
注解。
另外 Java 8也新增了许多内建的函数式接口,并对 Date
类的 API 进行了许多更新,这些不在这里详述。
有关更加详细的 Java 8新特性 可以看 这里 。
这个功能与iOS上弹出对话框向用户请求权限的方式类似,所有权限都可以在运行时请求,并可以由用户在设置里面自行开启/关闭权限开关(不过预览版里显示的权限种类只有7种,许多权限归在一个大类)。
开发者可以在M的 SDK 构建的 app里使用 Context.checkSelfPermission()
检查有无获取到权限以及通过 Activity.requestPermission()
方法请求权限。对于开发者带来的相应改变就是: 现在需要根据有无获取到权限写两套逻辑 ,当然一般未获取到权限的逻辑也相对简单。
另外有一个需要注意的是,这种运行时权限管理的功能只有在 M 之后的 SDK 构建的应用才有效,之前的 SDK 构建的依然是在安装时询问权限并默认全部允许,自己在设置里关闭权限有可能会引起 app 崩溃。
这个功能的目的是减少用户点击链接后因为有多个 app 具有相应 intent-filter
而弹出选择启动相应 app 对话框的情景。
现在开发者可以将一个web域名 与自家 app 绑定,比如在浏览器里点击 facebook 域名时会直接打开 Facebook 官方app 不会有第三方客户端的机会。
有关怎么实现 app link 可以看这里的 中文教程
doze 模式的引入算是一种学习 iOS电源管理方式 的省电功能。根据官方文档描述,基本功能是:
当手机没有连接电源、屏幕关闭、并处于静止状态(放在口袋里走路就不行)一段时间后(一小时左右)会启动此模式,在doze模式下会有以下影响:
app网络连接会被停用, 只有使用具有高优先级比如 GCM网络连接的 app 可以正常工作;
wakelock 会被忽略;
使用 AlarmManager设定的定时任务会被忽略,除非是使用setAlarmClock()和AlarmManager.setAndAllowWhileIdle()方法设定;
同步和 JobScheduler 会停止工作;
wifi扫描会停止工作;
在 doze 模式下,国产 app理论上是无法向用户推送消息的( GCM 在国内是不存在的),应该说Google 这种举动是在有意强推 GCM,在 GCM 已经发展得足够稳定可靠的时候本是好事,奈何国内互联网环境如此奇葩,所以对国内用户并没有什么卵用。
而且现在已经找到了从 .so层绕过 doze模式限制的方法,虽然不知道等 M 正式版的时候这个应该算 Bug的东西会不会被修复。总之现在看来这个原本很赞的省电功能对国内用户来说真是鸡肋了。
这个功能是 M 致力于省电的另一个表现,具体特性是:
当 app 被认为处于闲置状态时停用它的同步功能与网络连接直到手机连接电源或恢复正常状态。当 app 处于后台不使用一段时间后就会进入闲置状态,除非系统收到以下信号:
这个功能有点自带 绿色守护 的意思。
现在系统会进行更严格的 APK 验证,当检查到在 Manifest
里声明的文件在 APK 中并不存在时,则认为此 APK不合法,需要重新生成签名。
在用户选择一段文本时,开发者可以设置一个弹出对话框让用户更方便的执行文字编辑操作:
全平台数据自动备份、通过Audio manager设置声音不再支持、指纹识别、相机服务改变、ART bug修复
Android M新特性官方文档
AppBarLayout
:一个垂直方向的 LinearLayout
,可以在其中放 ToolBar配合TabLayout
构成Material design下典型的 AppBar(比如 Play store那种) ;
NavigationView
:这个应该很熟悉了,就是那个根据导航不同做出好看动画的左上角导航图标,现在不需要使用第三方库了,原生支持并向后兼容;
FloatingActionButton
:又一个典型的 MD 控件;
TabLayout
:原生实现的顶部 Tab;
SnackBar
:官方建议替代 Toast 的一种控件;
CoordinatorLayout
:更加强大的 FrameLayout
,通过配合 FAB 等控件使用,可以方便的实现 MD 下一些滑动后动态改变界面布局的效果,方便实现不同控件间层级合理显示;
Collapsing Toolbars
:实现 MD 式滑动隐藏 Tab 效果的辅助 Layout;
TextInputLayout
:类似 这个 输入效果的 Layout;
现在可以在 Android studio 中使用 SVG 资源 了,实现一些复杂动画又有了新的方法。
AS 中直接集成了 JetBrains 家的 Clion,进行 C/C++开发更为方便。另外这个 Clion特别为 Android开发进行了优化,可以自动生成JNI 方法名。
现在可以通过在 XML
文件中进行 Data binding ,只需要在当前app模块添加如下依赖:
dependencies { classpath "com.android.tools.build:gradle:1.3.0-beta1" classpath "com.android.databinding:dataBinder:1.0-rc0" } }
就可以在布局文件中写下与业务逻辑、数据绑定的代码。
这个特性使得在 Android 开发中实现 MVVM 更为方便(之前有一个开源库 Android binding 就是致力于实现 MVVM ),有关这个问题我过两天再单独写一篇博客讨论。
5.语音API
现在有了可以在第三方app里配合语音输入使用的 API,用户可以通过语音输入与 app 进行交互。(前提是使用 Google voice input )
这个新 API 是为了将开发者开发 app 中的内容暴露给 Google now
分析,使用户能够通过 长按 Home呼出 Google now动态分析 app内容给出搜索结果或者推送相关内容 ,app 也可以通过此行为进行交互。
direct-share-screen_2x.png
可以直接指定分享方式(邮件、短信、FB)来对特定目标(比如联系人 app 中联系人)进行分享
9.其他
4K显示模式、相机 API 更新、音视频API
Android M新 API 官方文档
Google I/O 2015 为 Android 开发者带来了哪些福利?