写点什么

当 Android 的 Compat 库不能拯救你的时候,覆盖所有面试知识点

用户头像
Android架构
关注
发布于: 9 小时前

比如说当我们需要获取通知通道组(NotificationChannelGroup)的时候:


val groups = notificationManagerCompat.notificationChannelGroups


我们不需要担心通道组是否被所有操作系统版本支持,因为它实际上会被在 Compat 类中处理掉:


public List<NotificationChannelGroup> getNotificationChannelGroups() {if (Build.VERSION.SDK_INT >= 26) {return mNotificationManager.getNotificationChannelGroups()}return Collections.emptyList()}


如果我们是在 API 26 之前,我们只会得到一个空的列表,如果不是我们就会得到在 API 26 中引入的新通道组。


你可以在 [NotificationManagerCompat](


) 代码处找到更复杂的检查。


但如果你仔细观察,NotificationManagerCompat 会返回我们实际的 API 类。在上面的示例代码中列出了 NotificationChannelGroup,这并不是一个复制的 Compat 版本,不过因为它检查了 API 的可用性,我们可以安全使用它。


val groups = notificationManagerCompat.notificationChannelGroupsval channels = groups.flatMap {it.channels.filter { it.shouldShowLights() }}


这里我们只需要那些正在触发灯光的渠道组,也就是 API 26 及以上。由于我们使用的是比最低 SDK 级别更高的 API 级别的类,编译器会在这里警告我们:



编译器并不在意我们使用 NotificationManagerCompat 来达到目的。


我们有多种方法来解决这


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


个问题。



RequiresApi 注解添加到我们的方法中并没有什么意义,因为我们会简单地将警告移到调用函数中。用检查包围似乎已经过时了,因为这个检查已经由 NotificationManagerCompat 完成,如上图所示。


看来最好的选择是选择抑制这个警告。


@SuppressLint("NewApi")private fun checkChannels() {val groups = notificationManagerCompat.notificationChannelGroupsval channels = groups.flatMap {it.channels.filter { it.shouldShowLights() }}...}

新的需求即将到来

假设我们得到了额外的要求,我们需要过滤掉被屏蔽的组。我们可以为此添加一个简单的检查:


@SuppressLint("NewApi")private fun checkChannels() {val groups = notificationManager.notificationChannelGroupsval channels = groups.filterNot { it.isBlocked }.flatMap {it.channels.filter { it.shouldShowLights()}}...}


一切看起来都很好,对吗?

你完了!

但我们刚刚引入了一个崩溃!


原因是:isBlocked 是在 API 28 才引入的,而我们没有进行检查! 尽管我们使用了 NotificationManagerCompat,但我们还是遇到了 API 级别上的问题!


而且因为我们抑制了 NewApi 的警告,所以我们在这个问题上没有收到任何警告!


所以当涉及到抑制警告的时候,我们就应该更加审慎!

解决方案?

由于只有在方法级别上才能解决这个问题(不适用单个语句),最好的方法是编写能满足我们需求的单行的方法。


多亏了扩展函数,这可以非常容易地实现:


@SuppressLint("NewApi") // SDK 26fun NotificationChannelGroup.lightingChannels() =channels.filterLightingOnes()


@SuppressLint("NewApi") // SDK 26private fun List<NotificationChannel>.filterLightingOnes() =filter { it.shouldShowLights() }


如果我们在上面的例子中使用这种方法,我们在添加 isBlocked 的时候就会得到警告:

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
当 Android 的 Compat 库不能拯救你的时候,覆盖所有面试知识点