当 Android 的 Compat 库不能拯救你的时候,覆盖所有面试知识点
比如说当我们需要获取通知通道组(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
来达到目的。
我们有多种方法来解决这
个问题。
将 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
的时候就会得到警告:
评论