当前位置: 首页 > news >正文

Android firebase消息推送集成 FCM消息处理

FirebaseMessagingService 是 Firebase Cloud Messaging (FCM) 提供的一个服务,用于处理来自 Firebase 服务器的消息。它有几个关键的方法,你提到的 onMessageReceiveddoRemoteMessagehandleIntent 各有不同的用途。下面逐一解释这些方法的作用和用法:

1. onMessageReceived(RemoteMessage message)

当你的应用处于前台时,如果有消息到达,就会回调 onMessageReceived 方法。这里是处理接收到的消息的逻辑部分。

override fun onMessageReceived(message: RemoteMessage) {super.onMessageReceived(message)// 你可以根据消息(message)的内容来做相应的处理,// 比如展示通知,更新UI等。
}

2. doRemoteMessage()

FirebaseMessagingService 的官方文档中,并没有直接提及 doRemoteMessage 这个方法。它可能是某个特定项目或库中特有的方法,而不是 Firebase SDK 的一部分。如果它存在于你的代码或你使用的某个库中,可能需要查找特定的文档或源代码来了解其具体用途。

3. handleIntent(Intent intent)

handleIntent 方法在服务中处理意图(Intent)。它不是 FirebaseMessagingService 专有的方法,而是 Android Service 类的一部分,可能会在接收到 Intent 时被调用。然而,在处理 FCM 相关的任务中,你通常不需要直接覆写或调用 handleIntent 方法。FCM 服务通常会自动处理消息的接收和分发工作,包括将消息派发到 onMessageReceived 方法。

如果你需要在后台接收消息并触发一些行为,通常会使用 onMessageReceived 来实现逻辑,因为 FCM 为这种用例提供了足够的支持。

注意:如果你的应用在后台,Firebase 通常会自动处理消息。如果消息中包含了通知负载,系统可能会自动显示通知,而不会调用 onMessageReceived。如果想要确保后台消息也触发 onMessageReceived,需要在发送消息时仅使用数据负载(即不包含通知负载),并确保应用实现了适当的后台运行条件(例如,使用高版本的 targetSdkVersion,考虑到 Android 的后台执行限制等)。

总之,对于绝大多数使用 Firebase Cloud Messaging 的场景,你主要会与 onMessageReceived 方法打交道,对于特殊的或自定义的方法(如 doRemoteMessage),需要参考特定的文档或代码实现。

当你使用 Firebase Cloud Messaging (FCM) 发送消息时,消息可以包含两种类型的数据:

  1. 通知负载:当应用在前台运行时,通过 onMessageReceived 处理;当应用在后台或被杀死时,系统会自动处理。
  2. 数据负载:无论应用是在前台、后台还是被杀死,都会触发 onMessageReceived(需要特定格式的负载才会在后台触发)。

以下是如何在 FirebaseMessagingServiceonMessageReceived 方法中获取消息标题、消息体和任意附加的数据(如 deeplink)的一个示例:

完整的 FirebaseMessagingService 示例

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessageclass MyFirebaseMessagingService : FirebaseMessagingService() {override fun onMessageReceived(remoteMessage: RemoteMessage) {super.onMessageReceived(remoteMessage)// 获取消息标题和内容(消息负载)val title = remoteMessage.notification?.title ?: "Default Title"val messageBody = remoteMessage.notification?.body ?: "Default Message Body"// 获取数据(数据负载)val data = remoteMessage.dataval deeplink = data["deeplink"] // 假定有一个键为"deeplink"的数据// 展示通知sendNotification(title, messageBody, deeplink ?: "default_deeplink")}private fun sendNotification(title: String, messageBody: String, deeplink: String) {val channelId = "YOUR_CHANNEL_ID"createNotificationChannel()val builder = NotificationCompat.Builder(this, channelId).setSmallIcon(R.drawable.ic_launcher_foreground) // 更改为你的通知图标.setContentTitle(title).setContentText(messageBody).setPriority(NotificationCompat.PRIORITY_DEFAULT)with(NotificationManagerCompat.from(this)) {// notificationId 是定义通知的唯一 int 值notify(System.currentTimeMillis().toInt(), builder.build())}// 处理 deeplink 或是其他额外的逻辑...}// Android 8.0 及以上需要创建通知频道private fun createNotificationChannel() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val name = "Channel Name"val descriptionText = "Channel Description"val importance = NotificationManager.IMPORTANCE_DEFAULTval channel = NotificationChannel("YOUR_CHANNEL_ID", name, importance).apply {description = descriptionText}val notificationManager: NotificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagernotificationManager.createNotificationChannel(channel)}}
}

请注意,您需要修改 R.drawable.ic_launcher_foreground 到您实际的通知图标资源,同时 "YOUR_CHANNEL_ID" 应该替换为您应用中的实际通知频道 ID。

通过上述代码,当 FCM 消息到达时(无论应用在前台、后台还是被杀死),onMessageReceived 都将触发(前提是符合数据消息的接收条件),您可以获取消息中的标题、消息体和附加的数据(如 deeplink),然后根据这些信息展示一条自定义通知。

在使用 Firebase Cloud Messaging (FCM) 时,您的应用可以接收两种类型的消息:通知消息数据消息。处理这些消息的方式与应用的前台/后台状态有关,以及消息的类型。

onMessageReceived 方法

onMessageReceived 方法在以下情况下被调用:

  • 应用在前台时,不论消息类型。
  • 应用在后台或被杀死时,仅当消息是数据消息(或通知和数据的混合消息,在这种情况下,数据部分被送达)。

处理后台消息

当您的应用处于后台或被杀死状态时,如果是纯通知消息,FCM 会自动展示通知,无需编写额外的接收代码。此外,点击通知可以自动打开应用或启动指定的活动(Activity),您可以在消息中指定 click_action 字段来指定要启动的活动,并在该活动中处理深链接。

实现深链接的点击响应

为了在点击通知后执行消息中携带的深链接,您可以:

  1. 在发送的消息中,设定通知消息的 click_action 属性,并为其指定一个唯一的值。
  2. 在应用的 AndroidManifest.xml 中,给相应的活动(Activity)配置一个 Intent Filter,该 Intent Filter 捕捉上一步中定义的 click_action

例如,您的消息结构可能如下所示:

{"to" : "FCM_TOKEN","notification" : {"body" : "消息正文","title": "消息标题","click_action":"OPEN_ACTIVITY_1"},"data" : {"extra_info" : "some_extra_information","deep_link" : "yourapp://deeplink/path"}
}

然后,在 AndroidManifest.xml 中配置捕捉这个动作的活动:

<activityandroid:name=".YourActivity"><intent-filter><action android:name="OPEN_ACTIVITY_1" /><category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity>

YourActivity 中,您可以获取数据并处理深链接:

if (intent.extras != null) {val deepLink = intent.extras.getString("deep_link")// 根据 deepLink 进行导航或其他操作
}

注意

当您的应用在后台或被杀死时接收通知消息,并且您希望在用户点击通知时执行一些代码(如处理深链接)时,上述方法一般可以实现目的。但是,如果需要在应用在后台或被杀死时收到的数据消息也能展示通知,并在点击时执行相应深链接,您需要在 onMessageReceived 方法中手动构建并展示通知,并处理点击事件。这一点非常重要,因为在后台时,数据消息不会自动展示通知,必须手动实现。

综上,您不需要(也不应该)直接修改 handleIntent 方法来处理普通的 FCM 消息。相反,您应专注于根据消息的类型和应用的状态,合理地使用 onMessageReceived 并处理通知的创建与点击响应。

在 Android 中,如果你想在收到 Firebase Cloud Messaging (FCM) 消息后展示自定义样式的通知,你可以在 onMessageReceived 方法中创建并展示一个通知。这给了你完全的控制权,允许你自定义通知的外观和行为。

以下是创建并展示一个自定义样式通知的基本步骤:

步骤 1: 创建 Notification Channel(仅限 Android Oreo (API 26) 及以上版本)

为了确保通知在 Android Oreo 及以上版本中正常工作,你需要创建一个 Notification Channel。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val channelName = "YourChannelName"val channelDescription = "YourChannelDescription"val channelId = "YourChannelId"val importance = NotificationManager.IMPORTANCE_DEFAULTval channel = NotificationChannel(channelId, channelName, importance).apply {description = channelDescription}// 注册通道val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagernotificationManager.createNotificationChannel(channel)
}

步骤 2: 创建自定义样式的通知

你可以使用 NotificationCompat.Builder 并利用其提供的样式,如 BigTextStyle, InboxStyle, BigPictureStyle 等来定制通知的视觉样式。

val builder = NotificationCompat.Builder(this, channelId) // 使用创建的通道ID.setSmallIcon(R.drawable.ic_notification) // 设置小图标.setContentTitle("Example Title") // 设置通知标题.setContentText("Example Description") // 设置通知内容.setPriority(NotificationCompat.PRIORITY_DEFAULT) // 设置优先级// 添加自定义样式.setStyle(NotificationCompat.BigTextStyle().bigText("Here is a longer text!"))// 构建 PendingIntent 来处理点击事件(例如打开 Activity)
val intent = Intent(this, YourActivity::class.java).apply {flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)builder.setContentIntent(pendingIntent)
builder.setAutoCancel(true) // 点击通知后自动消失

这里,YourActivity::class.java 应该替换为你想要打开的 Activity 的实际类名。

步骤 3: 展示通知

最后,使用 NotificationManager 来展示你刚才创建的通知。不要忘记替换通知的 ID(notificationId),如果你想要展示多个通知,每个通知的 ID 都应该是独一无二的。

with(NotificationManagerCompat.from(this)) {// notificationId 是定义通知的唯一 int 值notify(notificationId, builder.build())
}

将以上步骤放在 onMessageReceived 方法内,这样每当你的应用接收到 FCM 消息时,都会展示一个定制化的通知。如果消息带有数据负载,你还可以根据这些数据来定制通知的内容和样式。

请注意,如果用户已经关闭了你的应用的通知权限,或者当前设备上的系统设置禁止了通知,那么这些通知将不会展示。因此,确保在应用中妥善地处理通知权限请求和指导用户如何在系统设置中启用通知。

如果您在处理 Firebase Cloud Messaging (FCM) 消息时正确配置了,通常不会出现两条通知的情况。这里是出现冲突可能情况的一些分析和建议:

1. FCM 通知类型

FCM 允许发送两种类型的消息:

  • 通知消息:当应用在后台时,消息会自动被 FCM 处理,显示为系统通知。如果应用在前台,onMessageReceived 会被调用,您有机会处理这个通知。
  • 数据消息:无论应用处于前台还是后台,onMessageReceived 都会被调用,您需要自己编写代码来生成并显示通知。

2. 消息处理

  • 当您的应用处于前台,并且收到了一个通知消息,您可以在 onMessageReceived 方法内自定义如何处理这个通知,包括展示自定义通知。
  • 当应用处于后台,并且收到了一个通知消息,系统会自动处理这个通知,展示一个系统通知。这种情况下,onMessageReceived 不会被调用。
  • 当应用处于前台或后台,并且收到了一个数据消息onMessageReceived 会被调用,您可以在其中处理数据并决定是否展示通知。

3. 避免冲突

如果您在前台手动处理并展示通知,同时您的消息是一个通知消息,可能会出现两个通知:一个是 FCM 自动创建的,一个是您自己创建的。为避免这种情况,有两种方法:

  • 使用数据消息:确保发送的是数据消息而非通知消息。这样,无论应用处于前台还是后台,onMessageReceived 都会被调用,而不会生成自动的系统通知,您可以在接收到消息时自由地处理并展示您自己的通知。
  • 合理设计通知显示逻辑:如果您需要发送通知消息(例如,确保后台应用也能接收),则可以在 onMessageReceived 里加入逻辑仅在应用处于前台时展示自定义通知。这样,当应用处于后台时,只有 FCM 生成的系统通知会被展示;当应用处于前台时,则根据您在 onMessageReceived 中的逻辑展示自定义通知。

总结

正确地选择和处理消息类型可以避免同时出现两条通知的问题。如果您完全控制通知的显示逻辑(尤其是选择数据消息),就可以按照自己的需求来设计通知的展示,而不会出现冲突。

重写 handleIntent(Intent intent) 方法来处理来自 Firebase Cloud Messaging (FCM) 的消息并不是官方推荐的方法,且很可能不解决您提出的问题。在 Firebase 的旧版本里,有些开发者通过重写 handleIntent 方法来在应用处于后台时截获和修改消息。然而,这种做法存在几个问题:

  1. 维护性和兼容性:直接重写基础服务的方法(如 handleIntent)可能导致在未来的库更新中出现兼容性问题。Firebase 和 Android 平台都在不断进化,直接依赖于这些内部实现的细节可能导致您的应用在未来某个时间点突然出现问题。

  2. 违背设计初衷:Firebase Messaging 设计的初衷是简化推送通知的处理。它区分了「通知消息」和「数据消息」,并为这两种类型的消息提供了不同的处理路径。通过恰当地使用这两种消息类型,您应该能够满足大部分的需求,而无需通过重写底层方法来实现特定的行为。

解决方案

如果您的目标是确保即使在应用处于后台或被杀死状态下也能按照自定义方式处理通知,您应该使用数据消息。发送数据消息而非通知消息,让您有机会在应用的 onMessageReceived 方法中捕获所有消息,并自定义如何处理这些消息和通知,无论应用处于前台还是后台。

当应用在后台或被杀死时收到数据消息,您可以在 onMessageReceived 方法中创建并显示自定义通知,这时可以使用 Android 的标准通知构建方法来自定义通知的展示。

确保在您的消息发送逻辑中,使用了数据消息。例如:

{"to": "device_token_or_topic","data": {"key1": "value1","key2": "value2",// 更多自定义的键值对}
}

在 Android 客户端,您的 FirebaseMessagingServiceonMessageReceived 方法将接收到这些消息,即使在应用被杀死的情况下也是如此:

override fun onMessageReceived(remoteMessage: RemoteMessage) {// Handle data payloadif (remoteMessage.data.isNotEmpty()) {val myData = remoteMessage.data["key1"] // 例子// 根据接收到的数据处理逻辑// 比如,生成自定义通知}
}

通过这种方式,您可以完全控制通知的生成和展示逻辑,而不需要依赖于 Firebase 自动处理通知的机制,这样就不会产生重复的通知,也避免了需要重写 handleIntent 方法的需求。

相关文章:

Android firebase消息推送集成 FCM消息处理

FirebaseMessagingService 是 Firebase Cloud Messaging (FCM) 提供的一个服务&#xff0c;用于处理来自 Firebase 服务器的消息。它有几个关键的方法&#xff0c;你提到的 onMessageReceived、doRemoteMessage 和 handleIntent 各有不同的用途。下面逐一解释这些方法的作用和用…...

react中怎么为props设置默认值

在React中&#xff0c;你可以使用ES6的类属性&#xff08;class properties&#xff09;或者函数组件中的默认参数&#xff08;default parameters&#xff09;来定义props的默认值。 1.类组件中定义默认props 对于类组件&#xff0c;你可以在组件内部使用defaultProps属性来…...

企业如何做好 SQL 质量管理?

研发人员写 SQL 操作数据库想必一定是一类基础且常见的工作内容。如何避免 “问题” SQL 流转到生产环境&#xff0c;保证数据质量&#xff1f;这值得被研发/DBA/运维所重视。 什么是 SQL 问题&#xff1f; 对于研发人员来说&#xff0c;在日常工作中&#xff0c;大部分都需要…...

半年不在csdn写博客,总结一下这半年的学习经历,coderfun的一些碎碎念.

前言 自从自己建站一来&#xff0c;就不在csdn写博客了&#xff0c;但是后来自己的网站因为资金问题不能继续维护下去&#xff0c;所以便放弃了自建博客网站来写博客&#xff0c;等到以后找到稳定&#xff0c;打算满意的工作再来做自己的博客网站。此篇博客用来记录自己在csdn…...

c++中的命名空间与缺省参数

一、命名空间 1、概念&#xff1a;在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存 在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c; 以避免命名冲突或…...

SpringBoot整合WebSocket实现聊天室

1.简单的实现了聊天室功能&#xff0c;注意页面刷新后聊天记录不会保存&#xff0c;后端没有做消息的持久化 2.后端用户的识别只简单使用Session用户的身份 0.依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…...

llama-factory学习个人记录

框架、模型、数据集准备 1.llama-factory部署 # 克隆仓库 git clone https://github.com/hiyouga/LLaMA-Factory.git # 创建虚拟环境 conda create --name llama_factory python3.10 # 激活虚拟环境 conda activate llama_factory # 安装依赖 cd LLaMA-Factory pip install -…...

VLC播放器(全称VideoLAN Client)

一、简介 VLC播放器&#xff08;全称VideoLAN Client&#xff09;是一款开源的多媒体播放器&#xff0c;由VideoLAN项目团队开发。它支持多种音视频格式&#xff0c;并能够在多种操作系统上运行&#xff0c;如Windows、Mac OS X、Linux、Android和iOS等。VLC播放器具备播放文件…...

跟小伙伴们说一下

因为很忙&#xff0c;有一段时间没有更新了&#xff0c;这次先把菜鸟教程停更一下&#xff0c;因为自己要查缺补漏一些细节问题&#xff0c;而且为了方便大家0基础也想学C语言&#xff0c;这里打算给大家开一个免费专栏&#xff0c;这里大家就可以好好学习啦&#xff0c;哪怕0基…...

学 C/C++ 具体能干什么?

学习 C 和 C 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;这两种语言以其高性能和低级控制而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 系统编程 C 和 C 是系统编程的首选语言&#xff0c;适用于操作系统、驱动程序和嵌入式系统开发。 操作系统开发…...

Django之Ajax实战笔记--城市级联操作

1. 项目架构搭建 1.1 创建项目tpdemo,创建应用myapp # 创建项目框架tpdemo$ django-admin startproject tpdemo$ cd tpdemo# 在项目中创建一个myapp应用$ python manage.py startapp myapp# 创建模板目录$ mkdir templates$ mkdir templates/myapp$ cd ..$ tree tpdemotpdemo…...

基于Netty实现WebSocket服务端

本文基于Netty实现WebSocket服务端&#xff0c;实现和客户端的交互通信&#xff0c;客户端基于JavaScript实现。 在【WebSocket简介-CSDN博客】中&#xff0c;我们知道WebSocket是基于Http协议的升级&#xff0c;而Netty提供了Http和WebSocket Frame的编解码器和Handler&#…...

27【Aseprite 作图】盆栽——拆解

1 橘子画法拆解 (1)浅色3 1 0;深色0 2 3 就可以构成一个橘子 (2)浅色 2 1;深色1 0 (小个橘子) (3)浅色 2 1 0;深色1 2 3 2 树根部分 (1)底部画一条横线 (2)上一行 左空2 右空1 【代表底部重心先在右】 (3)再上一行,左空1,右空1 (4)再上一行,左突出1,…...

【开源】2024最新python豆瓣电影数据爬虫+可视化分析项目

项目介绍 【开源】项目基于pythonpandasflaskmysql等技术实现豆瓣电影数据获取及可视化分析展示&#xff0c;觉得有用的朋友可以来个一键三连&#xff0c;感谢&#xff01;&#xff01;&#xff01; 项目演示 【开源】2024最新python豆瓣电影数据爬虫可视化分析项目 项目截图…...

[JDK工具-5] jinfo jvm配置信息工具

文章目录 1. 介绍2. 打印所有的jvm标志信息 jinfo -flags pid3. 打印指定的jvm参数信息 jinfo -flag InitialHeapSize pid4. 启用或者禁用指定的jvm参数 jinfo -flags [|-]HeapDumpOnOutOfMemoryError pid5. 打印系统参数信息 jinfo -sysprops pid6. 打印以上所有配置信息 jinf…...

【Linux系统编程】进程概念、进程排队、进程标识符、进程状态

目录 什么是进程&#xff1f; 浅谈进程排队 简述进程属性 进程属性之进程标识符 进程操作之进程创建 初识fork fork返回值 原理角度理解fork fork的应用 进程属性之进程状态 再谈进程排队 进程状态 运行状态 阻塞状态 挂起状态 Linux下的进程状态 “R”(运行状…...

Java与GO语言对比分析

你是不是总听到go与java种种对比&#xff0c;其中在高并发的服务器端应用场景会有人推荐你使用go而不是 java。 那我们就从两者运行原理和基本并发设计来对比分析&#xff0c;看看到底怎么回事。 运行原理对比 java java 中 jdk 已经帮我们屏蔽操作系统区别。 只要我们下载并…...

Linux文件系统原理

Linux文件系统 冯诺依曼在1945年提出计算机的五大组成部分 运算器&#xff1a;CPU 控制器&#xff1a;CPU 存储器&#xff1a;内存和硬盘 输入设备&#xff1a;鼠标、硬盘 输出设备&#xff1a;显示器一、硬盘结构 机械硬盘结构 扇区&#xff1a;硬盘的最小存储单位&#xff…...

初识Spring Cache:如何简化你的缓存处理?

文章目录 1、Spring Cache介绍2、 常用注解3、 使用案例 1、Spring Cache介绍 Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能。 Spring Cache 提供了一层抽象&#xff0c;底层可以切换不同的…...

攻防世界[GoodRe]

攻防世界[GoodRe] 学到知识&#xff1a; 逆向的精髓&#xff1a;三分懂&#xff0c;七分蒙。TEA 算法快速识别&#xff08;蒙&#xff09;&#xff1a; 数据处理的形式&#xff1a;进入加密时的数据和加密结束后的数据&#xff0c;处理时数据的分组等等&#xff0c;都能用来…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...

Java中HashMap底层原理深度解析:从数据结构到红黑树优化

一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一&#xff0c;是基于哈希表的Map接口非同步实现。它允许使用null键和null值&#xff08;但只能有一个null键&#xff09;&#xff0c;并且不保证映射顺序的恒久不变。与Hashtable相比&#xff0c;Hash…...

以太网PHY布局布线指南

1. 简介 对于以太网布局布线遵循以下准则很重要&#xff0c;因为这将有助于减少信号发射&#xff0c;最大程度地减少噪声&#xff0c;确保器件作用&#xff0c;最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确&#xff0c;然…...