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

创建Firebase项目并接入Firebase推送: Firebase Cloud Messaging (FCM)

1.FCM简介:

Firebase Cloud Messaging (FCM) 是一种跨平台消息传递解决方案,可供您可靠地传递消息,而且还是免费的服务。支持 Android,IOS,Web,Flutter,Unity.

消息类型

可以使用 FCM 向客户端发送两种类型的消息:

  • 通知消息,有时被称为“显示消息”。此类消息由 FCM SDK 自动处理。

  • 数据消息,由客户端应用处理。

通知消息包含一组用户可见的预定义键。与其相对,数据消息只包含用户定义的自定义键值对。通知消息可以包含可选的数据载荷。两种消息类型的载荷上限均为 4000 个字节,但从 Firebase 控制台发送消息时会强制执行 1024 个字符的限制。

使用情景

如何发送

通知消息

当客户端应用在后台运行时,FCM SDK 会代表客户端应用向最终用户设备显示消息。如果应用在收到通知时正在前台运行,应用的代码会决定行为。通知消息包含一组预定义的用户可见的键和一个由自定义键值对组成的可选的数据载荷。

  1. 在可信环境(例如 Cloud Functions 或应用服务器)中,使用 Admin SDK 或者 FCM 服务器协议:设置 notification 键。可能包含可选的数据载荷。 一律可折叠。

请参阅一些显示通知示例并发送请求载荷。

  1. 使用 Notifications Composer:输入消息文本、标题等,然后发送。通过提供自定义数据添加可选的数据载荷。

数据消息

客户端应用负责处理数据消息。数据消息仅包含自定义键值对,没有保留键名(请参阅下文)。

在可信环境(例如 Cloud Functions 或应用服务器中),使用 Admin SDK 或者 FCM 服务器协议:仅设置 data 键。

通知消息

如果要进行测试,或者要开展营销、重新吸引用户,可以使用 Firebase 控制台发送通知消息。Firebase 控制台提供基于分析的 A/B 测试,可帮助优化和改进营销消息。

如需使用 Admin SDK 或 FCM 协议以编程方式发送通知消息,可使用通知消息中用户可见部分所必需的预定义键值对选项集来设置 notification 键。例如,以下是即时通讯应用中的 JSON 格式的通知消息。用户可能会在设备上看到标题为“Portugal vs. Denmark”、文本为“great match!”的消息:

{"message":{"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...","notification":{"title":"Portugal vs. Denmark","body":"great match!"}}
}

应用在后台运行时,通知消息将被传递至通知面板。应用在前台运行时,消息由回调函数处理。

数据消息

使用自定义键值对设置适当的键,以将数据载荷发送至客户端应用。

请确保未在自定义键值对中使用任何保留字词。保留字词包括“from”“notification”“message_type”或以“google”或“gcm”开头的任何字词。

例如,下方所示为上述同一即时通讯应用中的一条 JSON 格式的消息,在此消息中,信息封装在常用的 data 键中,且客户端应用需要解读相应内容:

{"message":{"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...","data":{"Nick" : "Mario","body" : "great match!","Room" : "PortugalVSDenmark"}}
}

2.FCM 架构概览:

通过上图架构可以看到可以发送FCM的平台:

1:开发中常用的:项目服务端server端接入Firebase Admin SDK

2.客户端可以直接发送FCM

3.通过Firebase 操作台发送FCM

3.生命周期流:

  • 注册设备以接收来自 FCM 的消息。客户端应用的实例注册以接收消息,并获取唯一标识应用实例的注册令牌。

  • 发送和接收下行消息

  • 发送消息。应用服务器向客户端应用发送消息:

  1. 消息会在 Notifications Composer 或受信任的环境中编写,并且消息请求会被发送到 FCM 后端。

  1. FCM 后端接收消息请求,生成消息 ID 和其他元数据,并将其发送到平台特定的传输层。

  1. 当设备在线时,系统会通过平台特定的传输层将消息发送到设备。

  1. 在设备上,客户端应用会接收到消息或通知。

4.客户端接入:

第 1 步:创建 Firebase 项目

需要先创建一个要关联到 Android 应用的 Firebase 项目,然后才能将 Firebase 添加到 Android 应用。请访问了解 Firebase 项目以了解详情。

创建项目:https://console.firebase.google.com/?hl=zh-cn

第 2 步:在 Firebase 中注册您的应用

如需在 Android 应用中使用 Firebase,需要向 Firebase 项目注册的应用。注册应用的过程通常称为将应用“添加”到项目中。

第 3 步:添加 Firebase 配置文件

  1. 下载 Firebase Android 配置文件 (google-services.json),然后将其添加到应用中:

  1. 点击下载 google-services.json 以获取 Firebase Android 配置文件。

  1. 将配置文件移到应用的模块(应用级)根目录中。

google-server.json:

{"project_info": {"project_number": "200570714500","project_id": "testproject-82da6","storage_bucket": "testproject-82da6.appspot.com"},"client": [{"client_info": {"mobilesdk_app_id": "1:200570714500:android:31bd6c1683be9fb6a485d1","android_client_info": {"package_name": "com.test.project.android"}},"oauth_client": [{"client_id": "200570714500-g7s70nmqogiviequmsegmuo49kf8knnb.apps.googleusercontent.com","client_type": 1,"android_info": {"package_name": "com.test.project.android","certificate_hash": "b0bd34f3447d5d63bf620ae01a5bb494759ee845"}},{"client_id": "200570714500-b9i97kadm6me2b2hb9e7l3cmsop63ajk.apps.googleusercontent.com","client_type": 3}],"api_key": [{"current_key": "AIzaSyBys0WVyFocO8ulfPdqIWMKCPWvy1HlppY"}],"services": {"appinvite_service": {"other_platform_oauth_client": [{"client_id": "200570714500-b9i97kadm6me2b2hb9e7l3cmsop63ajk.apps.googleusercontent.com","client_type": 3}]}}}],"configuration_version": "1"
}

放到项目中的位置:放到项目的./app 目录下即可,如果要区分debug or release 那就可以根据多渠道创建对应的文件夹下:

第 4 步:将 Firebase SDK 添加到应用中

buildscript {repositories {// Make sure that you have the following two repositoriesgoogle()  // Google's Maven repositorymavenCentral()  // Maven Central repository}dependencies {...// Add the dependency for the Google services Gradle pluginclasspath 'com.google.gms:google-services:4.3.15'}
}allprojects {...repositories {// Make sure that you have the following two repositoriesgoogle()  // Google's Maven repositorymavenCentral()  // Maven Central repository}
}
dependencies {implementation platform('com.google.firebase:firebase-bom:31.2.0')implementation 'com.google.firebase:firebase-analytics'implementation 'com.google.firebase:firebase-auth'implementation 'com.google.firebase:firebase-firestore'implementation  'com.google.firebase:firebase-messaging'
}
plugins {id 'com.android.application'// Add the Google services Gradle pluginid 'com.google.gms.google-services'...
}

到此已经将Firebase sdk 引入到项目中了

5. FCM项目中使用:

5.1 首先创建一个类继承FirebaseMessagingService ,实现onMessageReceived()和 onNewToken()方法

class MessagingService : FirebaseMessagingService(), LifecycleObserver {/*** Called when message is received.** @param remoteMessage Object representing the message received from Firebase Cloud Messaging.*/override fun onMessageReceived(remoteMessage: RemoteMessage) {if (remoteMessage == null) {return}val remoteMessageMap: Map<String, String> = remoteMessage.data;if (remoteMessageMap == null || remoteMessageMap.isEmpty()) {return}val json = JSON.toJSON(remoteMessageMap) as JSONObject}override fun onNewToken(token: String) {try {MyApplication.instance?.let {ApiClient.getApiService(it.sessionManager).postPushToken(PushTokenBody(token))}val param = HashMap<String, Any>()param.put("fcm_registration_token", token)AppLog.setHeaderInfo(param)} catch (e: java.lang.Exception) {}}
}

onMessageReceived()是监听推送的消息,onNewToken()是当有新的Firebase token 时的回调,有新的 token 及时上传server

由于FirebaseMessagingService 是一个 service 所以要在AndroidManifest中声明:

        <serviceandroid:name=".ui.notification.MessagingService"android:exported="false"><intent-filter><action android:name="com.google.firebase.MESSAGING_EVENT" /></intent-filter></service>

5.2 启动APP时 获取firebase fcm token 上传server

初次启动APP时,FCM SDK 会为客户端应用实例生成一个注册令牌 (registration token),注意上面睡到 FirebaseMessagingService 并重写 onNewToken 来获取更新此token。

fcm token 可能会在发生下列情况时更改:

  • 应用在新设备上恢复

  • 用户卸载/重新安装应用

  • 用户清除应用数据。

获取fcm token:

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->if (!task.isSuccessful) {Log.w(TAG, "Fetching FCM registration token failed", task.exception)return@OnCompleteListener}// Get new FCM registration tokenval token = task.result// Log and toastval msg = getString(R.string.msg_token_fmt, token)Log.d(TAG, msg)Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {@Overridepublic void onComplete(@NonNull Task<String> task) {if (!task.isSuccessful()) {Log.w(TAG, "Fetching FCM registration token failed", task.getException());return;}// Get new FCM registration tokenString token = task.getResult();// Log and toastString msg = getString(R.string.msg_token_fmt, token);Log.d(TAG, msg);Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();}});

6.使用 Firebase 控制台发送消息进行测试

可以使用 Firebase 控制台中的 Notifications Composer 发送通知消息。尽管使用这种方法发送消息的灵活性或可伸缩性不及使用 Admin SDK 或 HTTP 和 XMPP 协议,但它非常适合用于测试或者针对性较强的营销活动及用户互动。Firebase 控制台提供基于分析结果的 A/B Testing 测试,可帮助优化和改进营销消息。

从 Notifications Composer 发送通知消息时,Google 以如下方式使用您在表单字段中输入的值:

  • 用户细分有效期等字段用于确定消息目标和传送选项。

  • 通知文字自定义数据等字段以由键值对构成的载荷形式发送至客户端。

这些字段会映射至使用 Message 对象时可用的键。例如,在编辑器的自定义数据字段中输入的键值对是作为通知的 data 载荷处理的。其他字段直接映射至 notification 对象或平台专用通知配置中的键。

请注意,Notifications Composer 中的某些字段在使用 FCM API 时不可用。例如,您可以根据应用版本、语言、浏览器类型、浏览器版本或用户属性来定位细分用户群,而这些方法均无法通过服务器 API 来使用。

Firebase 控制台向客户端发送的键有:

控制台字段标签

说明

notification.title

通知标题

指示通知标题。

notification.body

通知文字

指示通知正文。

data

自定义数据

您定义的键值对。它们以数据载荷的形式传送至应用以进行处理。

决定消息传送方式的键包括:

控制台字段标签

说明

sound

声音

指示设备收到通知时要播放的声音。

time_to_live

有效期

此参数指定设备离线后消息在 FCM 存储区中保留的时长(以秒为单位)。 如需了解详情,请参阅设置消息的有效期。

这样通过控制台发送的消息推送,APP的onMessageReceived()就能接收到该消息

这个时候当APP杀死或者切后台时,FCM SDK会直接走系统的notificaion.如果这个时候APP在activity status 收到push message 后就可以做独立的逻辑了

7.使用 Firebase Admin SDK for FCM发送消息

Admin FCM API 可处理后端身份验证工作,同时便于发送消息和管理主题订阅。使用 Firebase Admin SDK,可以执行以下操作:

  • 向单个设备发送消息

  • 向主题和与一个或多个主题匹配的条件语句发送消息。

  • 为设备订阅和退订主题

  • 针对不同目标平台构建量身定制的消息载荷。

Admin Node.js SDK 提供了用于向设备组发送消息的方法。

使用Firebase Admin SDK 需要从Firebase 控制台获取json:

控制台->设置-->项目设置-->服务账号-->生成新的秘钥

拿到的admin sdk json 样式:

{"type": "service_account","project_id": "testproject-82da6","private_key_id": "2dab734ab58df4f1b0898cde1e8c8b488ae3134d","private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCy3HNgzSSUTG8r\ny7CulZZr7CdW70UEfL6dbla1b9lmxdIDWmMz+/8tux8dSr7FKjvUhHjqF5R8Ua7b\nCySuvvwjhwHm9u9kC1bOmlOhzMMsfRCQqIFU5nPvq+6KIrELwrIk6wpwXof4+6ns\nUhPrOv3AyEi1+yeTlXipexsaQ1X45qPfCvAJea59DpbnObhtX0g5K5tp6IqwaXwg\ncXoUgTeQlkjG3f3Y5A/wNH2etAqzA299ixUyl/20hHyOY8wtTNj67ZgsW4bvufXF\n8+y2vm4i2eIgV1uvHpPRBHcH5lV8PJH8Pgd3n9dXDSuKDaq/zc87DbPC9ybSovLA\nkTnzUZWDAgMBAAECggEAVhz/S87Y2rGGIL7b3OJWXrV/J0LhpsxsdZ2HD6m/MNTz\nTPv6oS+lZx4dV9wBxymTTrlNAd/CdKxbFEjkK2H2QSCiENI45aDz9VqmA1NzcHry\nO8N1KSwfC3hqy4TyWqgtXsru5rUMoBqCcC4AOxPW0jdbkopOPqcLRgXoQZfDz6Zk\nhK2QhaIVbw2sHZZsCNYagRI+7AlS6VDT9FnREj5HoeyNFiNCT6th7Am6mi040mI1\nJaAJ2OhvNyW4vQpaLjT8Dadgw4uU3yLt+0wKtQJU83qNtgyiXnCNp4En7c+d/f0A\nrovZVpvA5LpVzokq+9nNTtrVEB1BmuxAyZnV/6I+eQKBgQDtCX791LezaSHAuIgL\nTlwQjCnd4nz+X2kYAACdfJMRHVuV2JcyHrV0Z+ICMX/hlqlyO9sP0Rs4gAfBtX2a\nerWzjT0OfhhJaTULY7nO/sXBNpsb/4LM4Ac6WN+gqL20Qp7ekExs5/cUoWjhsEQK\no+tauuMvAhGSG/Kz1ALa+5DmtQKBgQDBK4POi9+w9h+/FvlzKl6/1RSg1HAf3DyO\nsih+1dcb/YkptFH460tns3zq9AZBX3DAQPjb0yL8uEfdRBVtnCwEASVbujgKYZz+\ntsBkR6ZsPrBVsFP5bwvT6k7ioZgoQiriNwQkxrUa4Z9NdD/bWB6liEUp1f86vD03\noZ/bw2U2VwKBgCTvad5bmxRVuXCyUGCSoT3i2VM9y4RHkbSvq2je1HvCO1cqHMUu\ni8/LsCfvVqHsPBMUyJm6V6eCK7M/eIbtwApuY6kydM5bmmxf6cAbau0keR7vvY33\nCqlI1+/M22KPTvoXOhFuQ83vKMyiDrgpuq60mFnm1J4TxMnIq3k74eRRAoGBAKeH\nm8qYWKpa6vGJdVJCHuZ0YG2TkKKxGPwQ2zoVL3ghDMJUlvsw5bbMXbxPYtVzdo/m\nSW4s0R0onXryvzrOxQW8ELBa8pteSRBHYtgVo+og/EF0qX+cpT9m6H948kOIDzUd\nzcQvaYYkw0ojVfZfmESryIAeDjrcYqNK0x9/eNoFAoGBAJZ8+h0Fi0bonctG7TwC\nR0rRX04l1VeOnMLhlgXZp5z4lzl7Bpuuua2yJHRnuJyN46hUxv8aNNKYeQbv8tTD\nGbCxJnSmL636aYwPIBYylU74CjIoUmcC2ce7MoT7c9zXaZvEmhSWEyzHTDXTJwL4\nhbAsd2wwEC0PJuU/Ri3rfk+X\n-----END PRIVATE KEY-----\n","client_email": "firebase-adminsdk-62mnh@testproject-82da6.iam.gserviceaccount.com","client_id": "114249923120443166527","auth_uri": "https://accounts.google.com/o/oauth2/auth","token_uri": "https://oauth2.googleapis.com/token","auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-62mnh%40testproject-82da6.iam.gserviceaccount.com"
}

admin sdk 发送FCM message:

private static String getAccessToken() throws IOException {GoogleCredentials googleCredentials = GoogleCredentials.fromStream(new FileInputStream("service-account.json")).createScoped(Arrays.asList(SCOPES));googleCredentials.refreshAccessToken();return googleCredentials.getAccessToken().getTokenValue();
}

这种方式客户端也是可以收到FCM Message 的

--至:大新

相关文章:

创建Firebase项目并接入Firebase推送: Firebase Cloud Messaging (FCM)

1.FCM简介&#xff1a;Firebase Cloud Messaging (FCM) 是一种跨平台消息传递解决方案&#xff0c;可供您可靠地传递消息&#xff0c;而且还是免费的服务。支持 Android&#xff0c;IOS,Web,Flutter,Unity.消息类型可以使用 FCM 向客户端发送两种类型的消息&#xff1a;通知消息…...

MyBatis的简单使用

MyBatis是一个优秀的持久型框架用于简化JDBC开发&#xff0c;JDBC的原生写法普遍都很麻烦&#xff0c;还要写原汁原味的sql语句&#xff0c;mybatis将很多东西都放到了配置文件里面然后用少量代码简化了免除了几乎所有的JDBC代码以及设定参数和获取结果集的工作。MyBatis 可以通…...

最新的Windows docker安装方法

什么是Docker&#xff1f;关于Docker的相关概述&#xff0c;请看&#xff1a;Docker_面向架构编程的博客-CSDN博客在Windows10 or Windows11中安装docker主要就两步&#xff1a;1.安装wsl22. 安装docker一、安装WSL2安装wslwsl --install然后重启一下电脑在cmd窗口可以查看自己…...

2023软件测试工程师涨薪攻略,3年如何达到30K

1.软件测试如何实现涨薪 首先涨薪并不是从8000涨到9000这种涨薪&#xff0c;而是从8000涨到15K加到25K的涨薪。基本上三年之内就可以实现。 如果我们只是普通的有应届毕业生或者是普通本科那我们就只能从小公司开始慢慢往上走。 有些同学想去做测试&#xff0c;是希望能够日…...

【算法题】1927. 求和游戏

题目&#xff1a; Alice 和 Bob 玩一个游戏&#xff0c;两人轮流行动&#xff0c;Alice 先手 。 给你一个 偶数长度 的字符串 num &#xff0c;每一个字符为数字字符或者 ‘?’ 。每一次操作中&#xff0c;如果 num 中至少有一个 ‘?’ &#xff0c;那么玩家可以执行以下操…...

有趣的 Kotlin 0x10:操作符 ..<

操作符 …< ..< 操作符是 Kotlin 在 1.7.20 版本中引入的不包含尾部元素的左闭右开区间操作符。之前我们使用的比较多的操作符可能是 .. 和 until&#xff0c;两者均表示区间&#xff0c;前者是闭区间&#xff0c;后者则表示不包含末端元素的左闭右开区间。 OptIn(Expe…...

mysql数据库之索引使用原则

一、最左前缀法则。 1、如果索引使用了多列&#xff08;联合索引&#xff09;&#xff0c;要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始&#xff0c;并且不跳过索引中的列。 如果跳跃到某一列&#xff0c;索引将部分失效&#xff08;后面的字段索引失效&am…...

【Java】Spring Boot 日志文件

文章目录SpringBoot日志文件1. 日志有什么用2. 日志怎么用3. 自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志4. 日志级别4.1 日志级别有什么用&#xff1f;4.2 日志级别的分类与使用5. 日志持久化6. 更简单的日志输出--lombok6.1 添加 lombok 依赖6.2 输出日…...

软件项目管理计算题复习(1)

软件项目管理计算题复习&#xff08;1&#xff09; 1.关键路径&#xff1a;决定项目最早完成的一系列的活动。网络图中最长的路&#xff0c;最少的时差&#xff0c;总是差为0&#xff0c;也是关键路径。 2.最短路径也是最短工期 3.总时差&#xff1a;最晚开始-最早开始最晚结…...

BMI160 BOSCH/博世 六轴 加速度 陀螺仪 传感器

BMI160 6轴惯性运动传感器&#xff0c;采用MEMS传感器封装&#xff0c;将16位3轴加速度计和超低功耗3轴陀螺仪集成在一起。当加速度计和陀螺仪在全速模式下运行时&#xff0c;耗电典型值低至950A&#xff0c;仅为市场上同类产品耗电量的50%或者更低。 Bosch BMI160专为智能手机…...

ROS探索[wpr_simulation的编译]

遇到的多种挑战最终的解决方式是通过重新删除所有编译文件夹重新生成工程原因如下 第一次生成的catkin_make文件的时候针对环境变量进行了设置,如果不删除环境变量相关的设置则后续新装的工具工程都会受到影响掣肘Protocbuf相关问题系统中存在多个版本的Protocbuf,因此优先级…...

连接Oracle数据库失败(ORA-12514)故障排除

文章目录症状产生原因解决办法欢迎加下方我的微信&#x1f447;&#xff0c;拉你入学习群点击试看博主的专著《MySQL 8.0运维与优化》&#xff08;清华大学出版社&#xff09;ORA-12514的故障是很多新手在连接Oracle数据库时经常遇到故障&#xff0c;它通常表示无法连接到数据库…...

DevOps 学习笔记(一) | DevOps 简介及环境搭建

1. 环境配置 本次实验需要三台服务器CI/CD 服务器、应用服务器和Harbor 服务器 DevOps 步骤 程序员将代码 push 到代码仓库Jenkins 根据触发条件拉取代码到CI/CD 服务器Jenkins 使用 Maven 将代码 build 成 jar 包Jenkins 使用 jar 包通过 Dockerfile 和 docker-compose.yml…...

日志收集笔记(Filebeat 日志收集、Logstash 日志过滤)

1 FileBeat Filebeat 是使用 Golang 实现的轻量型日志采集器&#xff0c;也是 Elasticsearch stack 里面的一员。本质上是一个 agent &#xff0c;可以安装在各个节点上&#xff0c;根据配置读取对应位置的日志&#xff0c;并上报到相应的地方去。 1.1 FileBeat 安装与使用 …...

字节二面,原来是我对自动化测试的理解太浅薄了..

如何使用Python实现自动化测试 如果你入职一家新的公司&#xff0c;领导让你开展自动化测试&#xff0c;作为一个新人&#xff0c;你肯定会手忙脚乱&#xff0c;你会如何落地自动化测试呢&#xff1f;资深测试架构师沉醉将告诉你如何落地自动kan化测试&#xff0c;本次话题主要…...

2023雅虎邮箱不能注册?别急,这份教程教你成功注册雅虎邮箱

这几年&#xff0c;跨境电商的迅猛发展&#xff0c;越来越多人加入这片蓝海&#xff0c;跨境人拥有一个专业的邮箱账户显得尤为重要&#xff0c;它是商业交流和日常工作的必备工具。因此&#xff0c;雅虎邮箱成为了许多人的首选&#xff0c;全球范围内使用雅虎邮箱的人数是非常…...

Elasticsearch 自动补全 completion type

Elasticsearch 自带一种自动补全类型 completion 这种类型不在mapping文档里面有点坑。 先直接上例子。 建立 index,把我们要自动补全的字段设置为 completion 类型 或者直接设置为子类型 PUT /blogs_completion/ {"mappings": {"tech": {"properties…...

GB28181协议实现源码Android源码

一、GB28181规范 尽管在国标GB28181中并没有对“平台”进行明确的定义,但在规范中却多次提到“系统平台”、“管理平台”等词汇,在具体项目中、网络上的交流学习中,平台概念也是无处不在。笔者认为,GB28181平台就是视频联网系统中的上级平台、中间平台或下级平台,用于实现…...

HNU工训中心: 三人表决器及八人抢答器实验报告

工训中心的牛马实验 三人表决器&#xff1a; 实验目的 1) 辨识数字IC功能说明。 2) 测试数字集成门电路&#xff0c;掌握输出故障排除、使用注意事项。 3) 掌握逻辑函数搭建三人表决器。 2.实验资源 HBE硬件基础电路实验箱、万用表 74LS00与非门、74LS10 三个3输入与非门…...

split()用法注意事项

split()用法注意事项 这个要注意有些特殊的分割符&#xff0c;比如.&#xff0c;这个表示匹配任何字符&#xff0c;如果在split()中调用的话&#xff0c;会将任何字符都分隔开&#xff0c;比如&#xff1a; String[] split "se.lll".split("."); System…...

centos7配置静态网络常见问题归纳

系列相似配置与安装软件问题整理与归纳文章目录 安装pymysql库_pymysql库安装_张小鱼༒的博客-CSDN博客 解决pip更新的代码_pip更新代码_张小鱼༒的博客-CSDN博客 python当中的第三方wxPython库的安装解答_pip install wx_张小鱼༒的博客-CSDN博客 spark里面配置jdk后的编程…...

产品经理修炼指南【01】

最近看了点产品经理的书&#xff0c;觉得产品经理这个位置和程序员不太一样&#xff0c;程序员唯一考核的标准就是能不能完成工作任务、是否能完成工作代码&#xff0c;但是产品经理貌似不一样&#xff0c;就像我给刘曼说的&#xff0c;产品经理上可以接领导&#xff0c;下可以…...

NCRE计算机等级考试Python真题(十一)

第十一套试题1、以下选项对于import保留字描述错误的是&#xff1a;A.import可以用于导入函数库或者库中的函数B.可以使用from jieba import lcut 引入 jieba库C.使用import jieba as jb&#xff0c;引入函数库jieba&#xff0c;取别名jbD.使用import jieba 引入jieba库正确答案…...

cglib代理解析

工作原理 使用 <dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency>对类和接口分别进行代理 DemoService package com.fanqiechaodan.user.service;/*** author fa…...

GFD563A101 3BHE046836R0101

GFD563A101 3BHE046836R0101关于高端涂布机张力控制系统方案的介绍高端涂布机张力控制系统方案涂布机是将具有某种功效的胶&#xff0c;或者油墨类物质均匀粘连在塑料薄膜、铝箔、纺织品等表面的机械设备。本系统从放卷到收卷共采用七台变频器&#xff0c;其中收放卷采用闭环张…...

SAP 采购定价过程字段解析

下面我们针对每一个字段进行解释和用途分析 &#xff1a; 1、 步骤&#xff1a;代表了创建PO时&#xff0c;哪个条件类型放到前面&#xff0c;哪个放到后面&#xff0c;如果步骤号相同&#xff0c;那就以谁先选择出来谁就在前面。 2、 计数&#xff1a;没有任何实际意义&a…...

一篇搞懂tcp,http,socket,socket连接池之间的关系

前言 作为一名开发人员我们经常会听到HTTP协议、TCP/IP协议、UDP协议、Socket、Socket长连接、Socket连接池等字眼&#xff0c;然而它们之间的关系、区别及原理并不是所有人都能理解清楚&#xff0c;这篇文章就从网络协议基础开始到Socket连接池&#xff0c;一步一步解释他们之…...

【JavaSE】对象的比较

哈喽&#xff0c;大家好&#xff01;我是保护小周ღ&#xff0c;本期为大家带来的是Java中自定义类型&#xff08;对象&#xff09;的三种比较方式&#xff0c;equals 方法, Comparable 泛型接口, Comparator 泛型接口 。在日常编程中&#xff0c;我们常常会需要比较的问题&…...

Leetcode DAY 49~50:买卖股票的最佳时机 1 2 3 4

121. 买卖股票的最佳时机 1、贪心算法 class Solution { public:int maxProfit(vector<int>& prices) {//贪心int low INT_MAX;int res 0;for(int i 0; i < prices.size(); i) {low min(low, prices[i]); //左最小价格res max(res, prices[i] - low); //当前…...

Android Handler机制(二) Handler 实现原理

一. 前言 接上一篇文章为什么设计Handler , 我们来继续讲解一下Handler的实现原理, 俗话说一个好汉三个帮, 接下来一步一步引入各个主角,并说明它们在Handler机制中扮演的角色和作用. 二. Handler实现原理 首先我们先确定一个结论: 使用 Handler 是希望它被实例化在哪个线程&a…...

门户网站建设 请示/外贸网站建设流程

黄河科技学院课程编号代码设置及说明.doc黄河科技学院课程编号代码设置及说明为了配合专业培养计划的修订工作&#xff0c;便于计算机管理&#xff0c;现将我校所开的全部课程(包括必修课、选修课、辅修专业所开课程以及课外培养项目)进行统一编号&#xff0c;具体编号要求和说…...

成都设计网站的公司名称/代理怎么引流推广

首先需要安装python环境 见本人发表的&#xff1a;python及pycharm安装python及pycharm安装_susan花雨的博客-CSDN博客 用pip install 安装 pip install xlrd pip install xlwt pip install xlsxwriter pip list查看 python合并多个表格&#xff1a;可以将每个表的不同she…...

建设网站 翻译/网站seo关键词设置

最近负责的邮箱系统项目中有一个这样的需求&#xff1a;提供一个接口给业务层&#xff0c;可以通过邮箱查询到该用户的未读邮件个数。 之前的方案是通过查看用户目录下.INBOX/new目录中的文件个数&#xff0c;但是这个方法不准确&#xff0c;当有用户连接到邮箱服务器时&#x…...

大连网站策划/站长工具官网

转载请注明来源&#xff1a; http://blog.csdn.net/milado_nju/article/details/7300058 WebKit和Chromium的代码量很大(这两个项目都是几百万行代码的级别&#xff0c;不包括它们依赖的第三方库&#xff09;&#xff0c;读起来是相当的不容易。但是良好的代码组织结构很好的帮…...

珠海政府网站大湾区建设/济南网站seo哪家公司好

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class ConditionCommunication {/*** 这一个示例的学习应该和传统的线程通信相互对比&#xff0c;Condition的通信优点查看文…...

推广网站的步骤/花西子网络营销策划方案

直接上例题 eg&#xff1a; 给定一个整型变量 a &#xff0c;写两段代码&#xff0c;第一个设置 a 的 bit 3&#xff0c;第二个清除 bit 3。在以上两个操作中&#xff0c;要保持其他位不变。 分析&#xff1a; 使用 #define 和 bit masks 操作。这是一个有极高可移植性的方法…...