×

Android N (6.X) 开发者预览指南

96
单刀土豆
2016.07.14 17:25* 字数 2463

开发环境准备

在体验 Android N 新特性之前,还是有一些准备工作要做的。

  • 一部 Nexus 设备,目前支持 Android N 手机只有 Nexus 5X,Nexus 6,Nexus 6p,如果没有 Nexus 设备也没关系,可以使用模拟器,具体配置过程可以看这里
  • 更新 Android Studio 到 2.1 或更高版本,主要是 Android N 支持 Java 8,相应的引入了自家的新编译器 Jack,目前只有 2.1 或者更高版本才支持 Jack。
  • 安装 N Preview SDK,打开 SDK Manager,在 SDK Platforms 选项卡中选中 Android N Preview,在 SDK Tools 选项卡选中 Android SDK Build Tools、Android SDK Platform-Tools 和 Android SDK Tools,然后点击 OK,开始安装。
  • 更新 JDK 到 8,如果 JDK 低于 8,需要更新到 8。
  • 设置项目配置,如果是新建项目,直接在 Minimum SDK 选项列表中,选择 N: Android API 23, N Preview (Preview),如果是老项目,打开模块的 build.gradle,按照下面设置
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    ...
    defaultConfig {
        minSdkVersion 24
        targetSdkVersion 24
        ...
    }
    ...
}

完成上面的配置,下面就来体验 Android N 的新特性了。

一 多窗口支持

多窗口支持算是 Android N 众多新特性中给用户感知最明显的特性了。毕竟交互的变化对于普通用户来说是最明显的。

多窗口效果

用户可以一次在屏幕上打开两个应用,两个应用可以在“分屏”模式中左右并排或上下并排显示:

竖屏

横屏

切换到多窗口模式

打开 Overview 屏幕并长按 Activity 标题,则可以拖动该 Activity 至屏幕突出显示的区域,使 Activity 进入多窗口模式。或者长按 Overview 按钮,设备上的当前 Activity 将进入多窗口模式,同时将打开 Overview 屏幕,用户可在该屏幕中选择要共享屏幕的另一个 Activity

选择多窗口

让应用支持多窗口模式

如果应用是面向 Android N 开发的即 targetSdkVersion 是 24,在 AndroidManifest 中设置 <activity><application>android:resizeableActivity 属性可以启用和禁用多窗口模式,并且根 Activity 的属性设置适用于其任务栈中的所有 Activity, 如果未对该属性指定值,则该属性的值默认设为 true,即支持多窗口模式。

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.glgjing.n"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:resizeableActivity="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

如果应用的 targetSdkVersion 低于 24 或者 android:resizeableActivityfalse,则应用不支持多窗口模式,如果应用不支持多窗口,且用户尝试在多窗口模式下启动 Activity,该 Activity 将全屏显示,并弹出 toast 提示该应用不支持多窗口。

应用内监听多窗口状态

在 Android N 中 Activity 类中添加了以下新方法,以支持多窗口状态的查询和切换

  • Activity.isInMultiWindowMode() 调用该方法以确认 Activity 是否处于多窗口模式
  • Activity.onMultiWindowModeChanged(boolean isInMultiWindowMode) Activity 进入或退出多窗口模式时系统将调用此方法。 在 Activity 进入多窗口模式时,系统向该方法传递 true 值,在退出多窗口模式时,则传递 false

二 更加强大通知功能

Android N 引入了一些新 API,利用这些 API 可以定制更丰富、更强大的通知,接下来我们就看下到底有多强大。

新的样式模板

Android N 介绍了一些在显示 notification 时使用的新的模板。这些新的模板重新排版了之前 SDK 版本的模板,使他们看起来更加的简洁清爽。这些新的模板将自动的被系统适配使用,所以我们不需要改变代码来创建一个 notification。下面是新旧样式的对比图:

旧版
新版

PS:可以调用 setColor() 来设置 notification 的颜色值。

捆绑通知

在 Android N 中,我们可以捆绑 notification ,将一组相关的 notification 放在一起,就是一个单独的 notification 头部下显示多个 notification,按照惯例还是来看下效果图:

展开前

展开后

效果是不是很赞,用起来也比较方便,只是有一点需要注意你必须设置一个 notification 作为 ‘小组标题’,不然你的 notification 将不会以组的形式展现。可以通过 setGroupSummary(true)notification 设为小组标题,具体实现如下:

Notification group = new Notification.Builder(this)
    .setSmallIcon(R.drawable.avator)
    .setGroupSummary(true)
    .setGroup("GROUP")
    .build();
Notification group1 = new Notification.Builder(this)
    .setSmallIcon(R.drawable.avator)
    .setContentTitle("这是第一条消息")
    .setContentText("你好, 单刀土豆")
    .setGroup("GROUP")
    .build();
Notification group2 = new Notification.Builder(this)
    .setSmallIcon(R.drawable.avator)
    .setContentTitle("这是第二条消息")
    .setContentText("我们又见面了")
    .setGroup("GROUP")
    .build();
Notification group3 = new Notification.Builder(this)
    .setSmallIcon(R.drawable.avator)
    .setContentTitle("这是第三条消息")
    .setContentText("再见")
    .setGroup("GROUP")
    .build();
NotificationManager notificationManager =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFY_ID0, group);
notificationManager.notify(NOTIFY_ID1, group1);
notificationManager.notify(NOTIFY_ID2, group2);
notificationManager.notify(NOTIFY_ID3, group3);    

直接回复功能

先来看下实现效果,再看如何使用:

回复状态

输入状态

利用 Android N 中的直接回复功能,用户可以直接在通知界面内快速回复内容或更新任务列表等,当用户通过键盘回复时,系统会将文本回复附加到你为通知操作指定的 Intent,然后在接收 Intent 时取出回复的内容并进行后续的操作,大致流程如下:

1、利用 RemoteInput.Builder 创建 RemoteInput 对象

// KEY_TEXT_REPLY 是该 Input 操作的标识
// 后面需要通过它来取出输入的文本
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
    .setLabel(replyLabel)
    .build();

2、使用 addRemoteInput() 向 Notification.Action 添加 RemoteInput 对象

Intent intent = new Intent("ACTION_REPLY");
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification.Action actionReply = new Notification.Action.Builder(R.drawable.reply_icon, "回复", pendingIntent)
    .addRemoteInput(remoteInput)
    .build();

3、构建 Notification 对象并发送通知

Notification notification = new Notification.Builder(this)
    .setSmallIcon(R.drawable.reply_icon)
    .setLargeIcon(iconAvator)
    .setContentTitle("来自基友的一条信息")
    .setContentText("你好, 单刀土豆")
    .addAction(actionReply)
    .setColor(0x0f9d58)
    .build();
    
NotificationManager notificationManager =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFY_ID, notification);    

4、当用户点击回复操作,并输入完成后,接收发送出来的 Intent,并取出用户输入的内容:

Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
    // 这里通过之前的 KEY_TEXT_REPLY 来检索用户输入内容 
    String message = remoteInput.getCharSequence(KEY_TEXT_REPLY);
    // 取出用户输入的内容就可以执行后续业务了
    ...
}

5、更新通知,告知用户回复成功,在应用收到远程输入后,必须更新或取消通知,否则回复进度条一直在转菊花

Notification repliedNotification = new Notification.Builder(context)
    .setSmallIcon(R.drawable.ic_message)
    .setContentText(getString(R.string.replied))
    .build();
NotificationManager notificationManager =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFY_ID, notification);

新的自定义通知样式

Android N 以前 NotificationCompat 提供了三种扩展样式:BigPictureStyle, BigTextStyle, InboxStyle,具体用法可以参考Android 开发之 Notification 详解。Android N 引入了一项新的自定义通知样式 MessageStyle,使用 MessageStyle 类,您可以更改在通知中显示的多个标签,包括会话标题、其他消息和通知的内容视图,按照惯例我们先看效果:

扩展样式

下面是具体使用方法,还是比较简单的,和之前的扩展样式用法类似:

Notification notification = new Notification.Builder(this)
    .setSmallIcon(R.drawable.setting_info_on)
    .setContentTitle("MessagingStyle Example")
    .setContentText("subtitle")
    .setStyle(new Notification.MessagingStyle("单刀土豆")
        .setConversationTitle("周末聚餐")
        .addMessage("周末出去吃吧", timestamp1, null)
        .addMessage("好呀, 去哪吃 ?", timestamp2, "基友")
        .addMessage("去西单吧", timestamp3, null)
        .addMessage("OK, 不见不散", timestamp4, "基友"))
    .build();

三 对 AOT 和 JIT 进行了调整

先简单的说下 AOT(Ahead-Of-Time - 预先编译)和 JIT(Just-In-Time - 实时编译)的优缺点,比较粗糙的理解就是:AOT 执行快、安装慢、占内存占外存大;JIT 反之执行慢一点、安装快、占空间小。所以是各有优缺点,在 Dalvik 虚拟机中采用的是 JIT 方案,到 Android L(5.0) Google 正式将 ART 作为默认模拟器,并且用 AOT 代替了 JIT,现在 Android N 又将 JIT 引入,主要是为了 JIT 编译器对 AOT 编译器进行补充,既满足提升运行时性能,又能节省存储空间,加快应用更新和系统更新速度。

Android N 根据应用的实际使用以及设备上的情况管理每个应用的 AOT/JIT 编译。 Android 运行组件维护每个应用的热方法,并且可以预编译和缓存这些方法以实现最佳性能。对于应用的其他部分,在实际使用之前不会进行编译。这样可以提升应用的关键部分的性能,又能减少整个 RAM 的占用。整个过程会最大程度降低对设备电池的影响。 仅当设备处于空闲状态和充电时才进行编译,从而可以通过提前执行该工作节约时间和省电。

引入 JIT 编译器还有一个非常重要的好处就是:应用安装和系统更新的速度会大幅度提升,因为省去了优化步骤。再也不用面对这个讨厌的弹窗了。

优化中

四 更强大的低耗电模式(Doze)

Android 6.0 就已经开始引入 Doze 模式,但进入 Doze 模式的条件是:屏幕关闭、未连接外部电源、设备静止一段时间后

If a user leaves a device unplugged and stationary for a period of time, with the screen off, the device enters Doze mode

在 Android N 中,低电耗模式又前进了一步,不需要设备处于静止状态。只要屏幕关闭了一段时间,且设备未插入电源,就会进入低耗电模式,这意味着用户即使将设备放入口袋里也可以省电。

低耗电模式

五 后台进程管理优化

Android N 加大了对后台进程的管理,主要是删除了三个常用隐式广播:CONNECTIVITY_ACTIONACTION_NEW_PICTUREACTION_NEW_VIDEO,不过通过 Context.registerReceiver() 中注册的 BroadcastReceiver 将继续接收 CONNECTIVITY_ACTION 广播。所以如果你的应用接收了上面的广播,那就需要注意了,该适配的就适配吧。


六 新的系统服务:Data Saver

Android N 推出了 Data Saver 模式,这是一项新的系统服务,有助于减少应用使用的蜂窝数据。Data Saver 让用户可以控制应用使用蜂窝数据的方式,同时让开发者打开 Data Saver 时可以提供更多有效的服务。用户在 Settings 中启用 Data Saver 且设备位于按流量计费的网络上时,系统屏蔽后台流量消耗,同时指示应用在前台尽可能使用较少的流量,用户可以将特定应用加入白名单,允许应用在开启 Data Saver 的情况下使用计费流量。

设置

总结

Android N 到目前为止(2016-7)还在 Beta 阶段,正式版大概在 8、9月份,正式版可能会有些调整,详细内容可以参考 Android N for Developers

技术博客
Web note ad 1