有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android NotificationChannel与旧API的兼容性

我是安卓开发和Java新手,在使用最新版本中引入的类时,我对向后兼容性的处理有点困惑

我已经查看了安卓支持库并查看了各种可用的XXXCompat类。对于我所看到的那些api,它们看起来几乎是在VERSION.SDK_INT上分支并调用新的api或旧的api

我正在使用一个支持库(com.安卓.support:support-v4:27.1.1)版本,该版本的目标api比我的targetSdkVersion(25)版本更新。我的印象是这是预期的用例?能够使用较新的api编写代码,但在针对较旧的sdk时仍能正常工作

如果是,这怎么可能?例如ContextCompatis对startForegroundService有以下内容

public static void startForegroundService(@NonNull Context context, 
@NonNull Intent intent) {
    if (VERSION.SDK_INT >= 26) {
        context.startForegroundService(intent);
    } else {
        context.startService(intent);
    }
}

但是,在我针对的版本中,上下文没有方法startForegroundService。如果将这个If块粘贴到我的代码中,它将无法使用java: cannot find symbol ...编译

我只能假设,即使您针对较新的api进行编译(这样它就可以解析符号),如果这些符号在运行时不存在,只要不调用它们就不是问题了

因此,对于由XXXCompat类抽象的api调用来说,这是很好的,但是当使用像NotificationChannel这样的新类时。只有将我的targetSdkVersion增加到>;26.假设我这样做了,那么这门课就可以上了。我所看到的所有用途都可以

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
   NotificationChannel channel = ...
}

这是否意味着在运行时,对于较低的Build.VERSION.SDK_INT,符号NotificationChannel将不存在?如果我尝试在较低的安卓版本上实例化这个类,它会崩溃吗


共 (1) 个答案

  1. # 1 楼答案

    在奥利奥之前,你可以开始你的服务。对于Oreo和更高版本,服务需要在前台运行,因此在服务启动时发布通知,否则会被破坏

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(intent)
    } else {
        startService(intent)
    }
    

    要在Oreo及以上版本中发布通知,您需要创建一个通知频道,在Oreo之前,您只需将频道id添加到通知生成器(无需创建频道)。来自服务的代码片段:

    String channelId = "myAppChannel"
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // build notification channel
        createNotificationChannel(channelId, ...)
    }
    
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId)
    
    // Build your notification
    Notification notification = notificationBuilder
            .setOngoing(true)
            .setSmallIcon(icon)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build()
    
    // post notification belonging to this service
    startForeground(NOTIFICATION_ID, notification)
    

    创建createNotificationChannel函数时,只需用@RequiresApi(26)注释它