flutter和原生利用pigeon建立通道
首先导入依赖:
dependencies:
pigeon: ^10.0.0
定义一个文件:
/// 用于定于flutter和平台的桥接方法
/// @HostApi() 标记的,是用于 Flutter 调用原生的方法;
/// @FlutterApi() 标记的,是用于原生调用 Flutter 的方法;
/// @async 如果原生的方法,是步回调那种,你就可以使用这个标记;
/// 在项目根目录,运行以下命令生成平台代码
/// dart run pigeon --input pigeons/messages.dartimport 'package:pigeon/pigeon.dart';@ConfigurePigeon(PigeonOptions(dartOut: 'lib/pigeons/pigeon.dart',dartOptions: DartOptions(),// objcHeaderOut: '../isolarCloud/operation4ios/Flutter/SGFlutterBridge.h',// objcSourceOut: '../isolarCloud/operation4ios/Flutter/SGFlutterBridge.m',// objcOptions: ObjcOptions(),kotlinOut:'../iSolarCloud/LibBase/src/main/java/com/isolarcloud/libbase/flutter/SGFlutterBridge.kt',kotlinOptions: KotlinOptions(),
))
class CommonParams {String? pageName;Map<String?, Object?>? arguments;
}
class ApiParams {String? url;Map<String?, Object?>? arguments;
}/// Flutter调用原生的Api,全部放在一个抽象类中即可
@HostApi()abstract class SGHostApi {/// push至原生页面,参数:页面名称、参数void pushNativePage(CommonParams params);/// pop出当前页面,预留参数,可通过params.pageName pop到指定页面void popPage(CommonParams? params);/// 通过Key获取本地化文本数据(同步)String getLocalizedText(String? key);/// Flutter通过URL和arguments调用原生端接口,异步返回数据给Flutter端@asyncMap requestNativeApi(ApiParams apiParams);/// 是否允许开启Native页面的原生手势返回效果void enablePopRecognizer(bool enable);
}
运行命令行:
dart run pigeon --input pigeons/messages.dart
接着可以运行下:flutter pub get 的命令
自动会生成这个文件:
里面会实现SGHostApi的定义的方法:比如下面的方法就是自动生成:
/// push至原生页面,参数:页面名称、参数
Future<void> pushNativePage(CommonParams arg_params) async {final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>('dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.pushNativePage', codec,binaryMessenger: _binaryMessenger);final List<Object?>? replyList =await channel.send(<Object?>[arg_params]) as List<Object?>?;if (replyList == null) {throw PlatformException(code: 'channel-error',message: 'Unable to establish connection on channel.',);} else if (replyList.length > 1) {throw PlatformException(code: replyList[0]! as String,message: replyList[1] as String?,details: replyList[2],);} else {return;}
}
注意打开这个代码注释:意思是在你Android项目的某个路径下生成SGFlutterBridge文件。
kotlinOut:'../iSolarCloud/LibBase/src/main/java/com/isolarcloud/flutter/SGFlutterBridge.kt',
kotlinOptions: KotlinOptions(),
然后会在:上面这个路径下自动生成和原生的桥接方法,这里执行的是Android的方法,ios只需要打开:
// objcHeaderOut: '../isolarCloud/operation4ios/Flutter/SGFlutterBridge.h',// objcSourceOut: '../isolarCloud/operation4ios/Flutter/SGFlutterBridge.m',// objcOptions: ObjcOptions(),
我们先看看原生和flutter项目的依赖:
在Android的项目settings.gradle中配置引用:
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir,'../isolarcloud_flutter/.android/include_flutter.groovy')
)
以上操作就把两个项目关联在一起了。下面是自动生成的桥接方法,pigeon自动帮你实现:
/*** Flutter调用原生的Api,全部放在一个抽象类中即可** Generated interface from Pigeon that represents a handler of messages from Flutter.*/
interface SGHostApi {/** push至原生页面,参数:页面名称、参数 */fun pushNativePage(params: CommonParams)/** pop出当前页面,预留参数,可通过params.pageName pop到指定页面 */fun popPage(params: CommonParams?)/** Flutter通过URL和arguments调用原生端接口,异步返回数据给Flutter端 */fun requestNativeApi(apiParams: ApiParams, callback: (Result<String?>) -> Unit)/** 是否允许开启Native页面的原生手势返回效果 */fun enablePopRecognizer(enable: Boolean)/*** 调用原生toast* type:0 老版,1:国内,2:海外样式*/fun showToast(type: AppType, msg: String)/*** 调用原生toast* type:0 老版,1:国内,2:海外样式*/fun showLoading(show: Boolean, type: AppType, msg: String?)/** 获取用户信息 */fun getUserInfo(): String?companion object {/** The codec used by SGHostApi. */val codec: MessageCodec<Any?> by lazy {SGHostApiCodec}/** Sets up an instance of `SGHostApi` to handle messages through the `binaryMessenger`. */@Suppress("UNCHECKED_CAST")fun setUp(binaryMessenger: BinaryMessenger, api: SGHostApi?) {run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.pushNativePage", codec)if (api != null) {channel.setMessageHandler { message, reply ->val args = message as List<Any?>val paramsArg = args[0] as CommonParamsvar wrapped: List<Any?>try {api.pushNativePage(paramsArg)wrapped = listOf<Any?>(null)} catch (exception: Throwable) {wrapped = wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.popPage", codec)if (api != null) {channel.setMessageHandler { message, reply ->val args = message as List<Any?>val paramsArg = args[0] as CommonParams?var wrapped: List<Any?>try {api.popPage(paramsArg)wrapped = listOf<Any?>(null)} catch (exception: Throwable) {wrapped = wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.requestNativeApi", codec)if (api != null) {channel.setMessageHandler { message, reply ->val args = message as List<Any?>val apiParamsArg = args[0] as ApiParamsapi.requestNativeApi(apiParamsArg) { result: Result<String?> ->val error = result.exceptionOrNull()if (error != null) {reply.reply(wrapError(error))} else {val data = result.getOrNull()reply.reply(wrapResult(data))}}}} else {channel.setMessageHandler(null)}}run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.enablePopRecognizer", codec)if (api != null) {channel.setMessageHandler { message, reply ->val args = message as List<Any?>val enableArg = args[0] as Booleanvar wrapped: List<Any?>try {api.enablePopRecognizer(enableArg)wrapped = listOf<Any?>(null)} catch (exception: Throwable) {wrapped = wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.showToast", codec)if (api != null) {channel.setMessageHandler { message, reply ->val args = message as List<Any?>val typeArg = AppType.ofRaw(args[0] as Int)!!val msgArg = args[1] as Stringvar wrapped: List<Any?>try {api.showToast(typeArg, msgArg)wrapped = listOf<Any?>(null)} catch (exception: Throwable) {wrapped = wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.showLoading", codec)if (api != null) {channel.setMessageHandler { message, reply ->val args = message as List<Any?>val showArg = args[0] as Booleanval typeArg = AppType.ofRaw(args[1] as Int)!!val msgArg = args[2] as String?var wrapped: List<Any?>try {api.showLoading(showArg, typeArg, msgArg)wrapped = listOf<Any?>(null)} catch (exception: Throwable) {wrapped = wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.getUserInfo", codec)if (api != null) {channel.setMessageHandler { _, reply ->var wrapped: List<Any?>try {wrapped = listOf<Any?>(api.getUserInfo())} catch (exception: Throwable) {wrapped = wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}}}
}
同步或者异步的去调用自动生成的方法:
Future<void> makeApiCall() async {var arguments = {"curPage": 1, "size": 10, "message_scene_code": 2};final stopwatch = Stopwatch()..start();await SGHostApi().requestNativeApi(ApiParams(arguments: arguments)).then((value) {print("数据回来的时间:${DateTime.now().millisecondsSinceEpoch}");stopwatch.stop();print("总共花费时间:${stopwatch.elapsedMilliseconds}毫秒");toast = "android 返回的数据==$value";// print("value===$value");setState(() {});});
}_getString(){SGHostApi().getLocalizedText("I18N_COMMON_SERVICE_AGREEMENT_DESCRIPTION").then((value){print("android 给过来的数据==$value");});setState(() {});
}
Android的代码:
class SingleFlutterActivity : FlutterActivity(), EngineBindingsDelegate {private val engineBindings: EngineBindings by lazy {EngineBindings(activity = this, delegate = this, entrypoint = FlutterRouter.DEMO_ENTRY_POINTER, initialRoute = "${FlutterRouter.DEMO_ROUTER}?psId=1234")}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)engineBindings.attach()/*** flutter 调用原生的方法* */SGHostApiget.setUp(getFlutterEngine()!!.getDartExecutor().getBinaryMessenger(), MyApi())SGHostApi.setUp(getFlutterEngine()!!.getDartExecutor().getBinaryMessenger(),FlutterToNativeApi() )}override fun onDestroy() {super.onDestroy()engineBindings.detach()}override fun provideFlutterEngine(context: Context): FlutterEngine? {return engineBindings.engine}override fun onNext() {val flutterIntent = Intent(this, LoginActivity::class.java)startActivity(flutterIntent)}/*** flutter 调用原生的方法,原生写法* */override fun onNext(str: String?) {val flutterIntent = Intent(this, FlutterToAndroidActivity::class.java)flutterIntent.putExtra("extraString", str)startActivity(flutterIntent)}/*** flutter 调用原生的方法* */class MyApi : SGHostApiget {override fun getString(): String {println("测试===6666")return "测试===6666,这里是Android的方法"}}/*** flutter 调用原生的方法* */class FlutterToNativeApi() : SGHostApi {/*** flutter调用原生跳原生页面* */override fun pushNativePage(params: CommonParams) {//params.pageName 页面名称非类名,不可直接创建实例/*val flutterIntent = Intent(this, params::class.java)flutterIntent.putExtra("extraString", str)startActivity(flutterIntent)*/}/*** flutter调用原生跳原生页面* */override fun popPage(params: CommonParams?) {//flutter调用Android去退出页面}/*** flutter调用原生 获取国际化字符串* */override fun getLocalizedText(key: String?): String {return I18nUtil.getString(key);}/*** flutter调用原生 获取网络信息 异步* */override fun requestNativeApi(apiParams: ApiParams,callback: (Result<Map<Any, Any?>>) -> Unit,) {/*val bitmap: Bitmap = BitmapFactory.decodeResource(BaseApplication.getApplication().resources, R.drawable.test_image)val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()bitmap.compress(Bitmap.CompressFormat.PNG, 50, outputStream)val size: Int = outputStream.size()println("字节大小: $size")val result: Result<Map<Any, Any?>> = Result.success(mapOf("name" to outputStream),)callback(result)*/val map: MutableMap<String, Any> = HttpRequest.getCommonParamMap()HttpUtil.postWithPath("/v1/devService/getDevModelUpgradeConfigList", /*apiParams.arguments*/map, object : HttpGlobalHandlerCallback<UpdateRequestBean?>() {override fun onSuccess(jsonResult: JsonResults<UpdateRequestBean?>) {// 处理成功返回的数据val data = jsonResult.result_data // 获取数据if (data is UpdateRequestBean) {data as UpdateRequestBean}println("开始传输时间: ${System.currentTimeMillis()}")callback(Result.success(data!!.toMap())) // 通过callback返回结果// 打印字节大小val byteArray = data?.toString()?.toByteArray(Charsets.UTF_8)val size = byteArray?.size ?: 0println("字节大小: $size")}fun UpdateRequestBean.toMap(): Map<Any, Any?> {val map = mutableMapOf<Any, Any?>()map["code"] = codemap["record"] = recordmap["totalFileSize"] = totalFileSizemap["pageList"] = pageList?.map { fileInfo ->mapOf("file_url" to fileInfo.file_url,"file_signature" to fileInfo.file_signature,"file_name" to fileInfo.file_name,"file_id" to fileInfo.file_id,"dev_model" to fileInfo.dev_model,"file_size" to fileInfo.file_size,"type" to fileInfo.type,"dev_type_id" to fileInfo.dev_type_id,"record_id" to fileInfo.record_id,"sn" to fileInfo.sn,"update_time_stamp" to fileInfo.update_time_stamp,"block_flag" to fileInfo.block_flag)}return map}override fun onError(type: ErrorNetType) {super.onError(type)// 处理错误情况// val result: Result<Map<Any, Any?>> = Result.success(// mapOf(// "name" to "John",// "age" to 30,// "email" to "john@example.com"// )// )// callback(result)// 通过callback返回错误信息val failureResult: Result<Map<Any, Any?>> = Result.failure(Exception("An error occurred"))callback(failureResult)}override fun onFinish() {super.onFinish()}})}override fun disablePopRecognizer(disable: Boolean) {}}}
在flutter中统一使用这个类来获取原生获取的网络数据:
/// 成功回调
typedef SuccessCallback = void Function(Map<String, dynamic>? resultData, String resultCode, String resultMsg);/// 失败回调
typedef ErrorCallback = void Function();class RequireNativeApi {static void postWithPathOversea(String? url, Map<String?, Object?>? arguments,SuccessCallback? successCallback, ErrorCallback? errorCallback,{bool showToast = true}) {postWithPath(url, arguments, successCallback, errorCallback,showToast: showToast, appType: AppType.oversea);}static void postWithPathDomestic(String? url,Map<String?, Object?>? arguments,SuccessCallback? successCallback,ErrorCallback? errorCallback,{bool showToast = true}) {postWithPath(url, arguments, successCallback, errorCallback,showToast: showToast, appType: AppType.domestic);}static void postWithPath(String? url, Map<String?, Object?>? arguments,SuccessCallback? successCallback, ErrorCallback? errorCallback,{bool showToast = true, AppType appType = AppType.oversea}) {ApiParams apiParams = ApiParams();apiParams.url = url;apiParams.arguments = arguments;sgApi.requestNativeApi(apiParams).then((data) {debugPrint("");debugPrint("======================================================");debugPrint("api: $url");debugPrint("业务入参: $arguments");debugPrint("出参:$data");debugPrint("======================================================");if (data == null || data.isEmpty) {/// 网络异常if (showToast) {sgApi.showToast(appType, SGi18n.key("I18N_COMMON_NETWORK_ERROR"));}if (errorCallback != null) {errorCallback();}return;}var jsonData = json.decode(data);if (successCallback != null) {// 返回接口返回数据,需要调用各个实体类的方法,所以需要各个业务层将Map转为对应的实体类successCallback(jsonData['result_data'] ?? {},jsonData['result_code'] ?? "",jsonData['result_msg'] ?? "",);}}).onError((error, stackTrace) {debugPrint("RequireNativeApi error: $error");debugPrint("RequireNativeApi error: $stackTrace");if (showToast) {sgApi.showToast(appType, SGi18n.key("I18N_COMMON_NETWORK_ERROR_MESSAGE"));}if (errorCallback != null) {errorCallback();}});}
}
flutter中要使用的地方直接拿到成功和失败的回调即可:
RequireNativeApi.postWithPathOversea(Api.getDeleteUserMessage, argument,getDeleteMessageSuccess, () => SGOSLoadingToast.dismissLoading());
我项目中用的是getx,大家可以看看我完整的代码:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:isolarcloud_flutter/api/api.dart';
import 'package:isolarcloud_flutter/api/require_native_api.dart';
import 'package:isolarcloud_flutter/bean/home_msg_entity.dart';
import 'package:isolarcloud_flutter/bean/update_msg_entity.dart';
import 'package:isolarcloud_flutter/modules/demo/constant/constant_state_id.dart';
import 'package:isolarcloud_flutter/utils/hud/sg_os_loading_toast.dart';
import 'package:isolarcloud_flutter/utils/json_cache_util.dart';import 'sg_message_first_state.dart';class SGMessageHomePageLogic extends GetxController {final SGMessageHomePageState state = SGMessageHomePageState();static const idMessageClearUpdate = "message_clear_update";static const idMessageList = "message_list";static const idLoadFail = "message_load_fail";void getList(String labelStr, {bool isFirst = false}) async {state.labelStr = labelStr;isFirst ? SGOSLoadingToast.showLoading() : null;Map<String, Object> argument = {};var cache = await JsonCacheManageUtils.getCacheData(JsonCacheManageUtils.HomeMessageResponse,labelId: labelStr.toString()).then((value) {if (value != null) {return HomeMsgEntity.fromJson(value as Map<String, dynamic>);}});state.hasCache = false;if (cache is HomeMsgEntity) {state.pageList = cache;state.hasCache = true;update([idMessageList + labelStr.toString()]);}RequireNativeApi.postWithPathOversea(Api.getHomeMessageList, argument, getHomeMessageSuccess, () {isFirst ? SGOSLoadingToast.dismissLoading() : null;update([idLoadFail]);});}void getHomeMessageSuccess(Map<String, dynamic>? resultData, String resultCode, String resultMsg) {if (resultCode == "1" && resultData != null && resultData.isNotEmpty) {JsonCacheManageUtils.saveCacheData(JsonCacheManageUtils.HomeMessageResponse,labelId: state.labelStr,resultData);state.pageList = HomeMsgEntity.fromJson(resultData);}SGOSLoadingToast.dismissLoading();if (!state.hasCache) {update(["$idMessageList${state.labelStr}"]);}}/// clear 消息 传null为全部void updateUserAllMessage(dynamic messageSceneCode) {SGOSLoadingToast.showLoading();Map<String, dynamic> argument = {"is_all": 1,"message_scene_code": messageSceneCode,};RequireNativeApi.postWithPathOversea(Api.getUpdateUserMessage, argument,getClearMessageSuccess, () => SGOSLoadingToast.dismissLoading());}void getClearMessageSuccess(Map<String, dynamic>? resultData, String resultCode, String resultMsg) {if (resultCode == "1" && resultData != null && resultData.isNotEmpty) {state.updateBean = UpdateMsgEntity.fromJson(resultData);}SGOSLoadingToast.dismissLoading();update([idMessageClearUpdate]);}//删除单个消息大类void deleteUserMessage(String? ids, String? messageSceneCode, int index) {SGOSLoadingToast.showLoading();Map<String, dynamic> argument = {"ids": ids,"message_scene_code": messageSceneCode,};state.removeIndex = index;RequireNativeApi.postWithPathOversea(Api.getDeleteUserMessage, argument,getDeleteMessageSuccess, () => SGOSLoadingToast.dismissLoading());}void getDeleteMessageSuccess(Map<String, dynamic>? resultData, String resultCode, String resultMsg) {debugPrint("resultData: $resultData");if (resultCode == "1" && resultData != null && resultData.isNotEmpty) {state.deleteBean = UpdateMsgEntity.fromJson(resultData);}SGOSLoadingToast.dismissLoading();update([StateListenerId.messageDelete]);}///底部按钮删除全部选中的void deleteCheckMessage(List<HomeMsgPageList> messageHomeList) {SGOSLoadingToast.showLoading();StringBuffer messageSceneCodes = StringBuffer();for (int i = 0; i < messageHomeList.length; i++) {String? sceneCode = messageHomeList[i].messageSceneCode;messageSceneCodes.write(sceneCode);if (i != messageHomeList.length - 1) {messageSceneCodes.write(',');}}String result = messageSceneCodes.toString();if (result.isEmpty) {return;}Map<String, dynamic> argument = {"ids": null,"message_scene_code": result,};RequireNativeApi.postWithPathOversea(Api.getDeleteUserMessage, argument,getDeleteMessageSuccess, () => SGOSLoadingToast.dismissLoading());}
}
按理来说这个GetxController类是用来访问网络的类,这里用来和原生交互,就这样子。
最近工作忙,加班重,疏于思考,缺乏输出,望大家理解,有时间优化文章,敬请期待!
相关文章:

flutter和原生利用pigeon建立通道
首先导入依赖: dependencies: pigeon: ^10.0.0定义一个文件: /// 用于定于flutter和平台的桥接方法 /// HostApi() 标记的,是用于 Flutter 调用原生的方法; /// FlutterApi() 标记的,是用于原生调用 Flutter 的方法&…...

TCP连接分析:探寻TCP的三次握手
文章目录 一、实验背景与目的二、实验需求三、实验解法1. 预先抓包监测使用Wireshark工具2.进行TCP三次握手,访问www.baidu.com3.分析Wireshark捕获的TCP包 摘要: 本实验使用Wireshark工具,通过抓包监测和分析,深入研究了与百度服…...

gitHooks使用教程
1. 安装所需依赖 npm install eslint prettier husky lint-staged --save-dev 2.初始化 husky npx husky-init && npm install 这将创建一个 .husky/ 目录,并且在其中包含一个示例的 pre-commit 文件。 3.设置 pre-commit 钩子 npx husky add .husky/…...

2023.8 - java - 数组
声明数组变量 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法: dataType[] arrayRefVar; // 首选的方法或dataType arrayRefVar[]; // 效果相同,但不是首选方法int[] a {1,2,3};int b[] new int[10];TS:let a:…...

ChatGPT怎么辅助解决社会问题?
ChatGPT作为一个强大的自然语言处理模型,具有潜力辅助解决多种社会问题。其能力可以应用于信息传递、教育、宣传、意识提高等领域,为社会问题的解决提供支持。以下将详细探讨ChatGPT如何辅助解决社会问题。 **1. 教育与意识提高**: ChatGPT可…...

Rust之自动化测试(一):如何编写测试
开发环境 Windows 10Rust 1.71.1 VS Code 1.81.1 项目工程 这里继续沿用上次工程rust-demo 编写自动化测试 Edsger W. Dijkstra在他1972年的文章《谦逊的程序员》中说,“程序测试可以是一种非常有效的方法来显示错误的存在,但它对于显示它们的不存在…...

简单聊聊Https的来龙去脉
简单聊聊Https的来龙去脉 Http 通信具有哪些风险Https Http SSL/TLS对称加密 和 非对称加密数字证书数字证书的申请数字证书怎么起作用 Https工作流程一定需要Https吗? Http 通信具有哪些风险 使用明文通信,通信内容可能会被监听不验证通信双方身份&a…...

【注册岩土】Python土力学与基础工程计算.PDF-土中的应力
Python 求解代码如下: 1.#计算竖向有效自重应力2.h12#m3.h21.5#m4.h31#m5.gamma1 19# kN/m^36.gamma218# kN/m^37.gamma317# kN/m^38.sigma_c gammal * h1 gamma2*h2 gamma3 *h39.print("竖向有效自重应力…...

祝贺!Databend Cloud 和阿里云 PolarDB 达成认证
近日,北京数变科技有限公司旗下产品与阿里云 PolarDB 开源数据库社区展开产品集成认证。 测试结果表明,北京数变科技有限公司旗下产品《Databend Cloud(V1.25)》正式通过了《阿里云 PolarDB 数据库管理软件》的技术认证ÿ…...

SQL语言-01
SQL Structured Query Language 的简单介绍 SQL 中的书写规则 SQL 中的数据类型...

PyCharm软件安装包分享(附安装教程)
目录 一、软件简介 二、软件下载 一、软件简介 PyCharm是一种集成开发环境(IDE),专门为Python开发者设计。它是由捷克软件公司JetBrains开发的,为Python开发人员提供了高效、易用和功能丰富的工具集。 以下是PyCharm软件的主要…...

AI文本标注的概念,类型和方法
我们每天都在与不同的媒介(例如文本、音频、图像和视频)交互,我们的大脑对收集到的信息进行处理和加工,从而指导我们的行为。在我们日常接触到的信息中,文本是最常见的媒体类型之一,由我们交流使用的语言构…...

【AutoLayout案例04-游戏图片-按钮适配 Objective-C语言】
一、好,我们再看一个案例, 刚才,这个案例, 这么一个案例 这个案例,是什么意思呢, 这里给大家做一个3.5英寸、4.0英寸的屏幕适配, 因为我们这里图片,只有一个,就是4英寸的这么一个图片 什么意思呢,要求我们在3.5英寸的屏幕、和4英寸的屏幕的时候,都能正常显示这个图…...

Spring Boot业务系统如何实现海量数据高效实时搜索
1.概述 我们都知道随着业务系统的发展和使用,数据库存储的业务数据量会越来越大,逐渐成为了业务系统的瓶颈。在阿里巴巴开发手册中也建议:单表行数超过500万行或者单表容量超过2GB才推荐进行分库分表,如果预计三年后数据量根本达…...

面向对象的设计原则
设计模式 Python 设计模式:对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计 面向对象 三大特性:封装、继承、多态 …...

前端需要理解的工程化知识
1 Git 1.1 Git 常见工作流程 Git 有4个区域:工作区(workspace)、index(暂存区)、repository(本地仓库)和remote(远程仓库),而工作区就是指对文件发生更改的地方ÿ…...

【Terraform学习】使用 Terraform创建DynamoDB添加项目(Terraform-AWS最佳实战学习)
本站以分享各种运维经验和运维所需要的技能为主 《python》:python零基础入门学习 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…...

基于单片机教室人数实时检测系统
一、系统方案 主程序中main函数主要是引脚的初始化,给单片机引脚初始化,初始化LCD1602,初始化红外对管,通过对LCD1602赋值,采集进入教室的人数,显示在LCD1602上面进出人数我们采用按键的形式,检…...

alibabacloud的简单使用,nacos配置中心+服务中心。作者直接给自己写的源码
文章目录 依赖关键主要的程序启动文件配置文件bootstrap.yml依赖文件nacos配置中心上的文件截图 启动成功截图参考文档 依赖关键 SpringBoot版本和com.alibaba.cloud版本需要对应,不然会程序会启动失败作者使用的版本 SpringBoot: 2.1.6.RELEASE alibabacloud: 2.…...

Python爬虫:一个爬取豆瓣电影人像的小案例
从谷歌浏览器的开发工具进入 选择图片右键点击检查 
STM32CubeMX配置STM32G0 Standby模式停止IWDG(HAL库开发)
1.打开STM32CubeMX选择好对应的芯片,打开IWDG 2.打开串口1进行调试 3.配置好时钟 4.写好项目名称,选好开发环境,最后获取代码。 5.打开工程,点击魔术棒,勾选Use Micro LIB 6.修改main.c #include "main.h"…...

39.RESTful案例
RESTful案例 准备环境 Employee.java public class Employee {private Integer id;private String lastName;private String email;//1 male, 0 femaleprivate Integer gender; } //省略get、set和构造方法EmployeeDao.java package com.atguigu.SpringMVC.dao;import com.…...

Power Pivot 实现数据建模
一、简介 Excel中的透视表适合小规模数据;如果想在稍微大一些的数据中进行高性能透视表分析,就要使用Power Pivot;再大一些数据,可能就需要大数据分析服务来进行分析。 Power Pivot,可以让没有技术背景的企业业务人员…...

Ansible自动化运维之playbooks剧本
文章目录 一.playbooks介绍1.playbooks简述2.playbooks剧本格式3.playbooks组成部分4.运行playbooks及检测文件配置 二.模块实战实例1.playbooks模块实战实例2.vars模块实战实例3.指定远程主机sudo切换用户4.when模块实战实例5.with_items迭代模块实战实例6.Templates 模块实战…...

Docker - Docker安装MySql并启动
因为项目需要连接数据库,但是远程服务器上的mysql我不知道账户和密码,这个时候便是docker发挥作用的关键时刻了! 目录 docker安装安装gcc卸载老docker(如有)安装软件包设置镜像仓库更新yum软件包索引安装docker启动doc…...

SQL Server 2019导入txt数据
1、选择导入数据 2、选择Flat file Source 选择文件,如果第一行不是列名,就不勾选。 3、下一步 可以看看数据是否是对的 4、下一步 选择SQL server Native Client 11,数据库选择导入进的库 输入连接数据库的名字和要导入的数据库 下一…...

科研 | Zotero导入无PDF的参考文献、书籍
最近在用Zotero在Word中插入参考文献的时候发现,有些没在网上找到对应的PDF版本,但也不是必须要PDF版本的参考文献或者参考书籍,如何才能不影响正常的文献排版 主要是先在网上找到对应文献,书籍,网页等的ISBN…...

【Docker】docker入门之dockerfile编写
文章目录 前言一、docker是什么?docker介绍docker指令 二、docker有什么用?三、docker怎么用?FROMMAINTAINERRUNENVWORKDIRCOPY、ADDUSEREXPOSE实例 四、docker注意事项docker容器中使用某些宿主机设备时需要额外的权限docker容器中文件内容中…...

javaee之黑马乐优商城1
问题1:整体的项目架构与技术选型 技术选型 开发环境 域名测试 如何把项目起来,以及每一个目录结构大概是什么样子 通过webpack去启动了有个项目,这里还是热部署,文件改动,内容就会改动 Dev这个命令会生成一个本地循环…...

滴滴前端一面面经(已挂)
面试过程 前段时间面试了滴滴的前端实习岗位,大厂的面试机会很难得,复习了很多前端知识。 拿到面试机会,是在地铁上投递了boss,当时hr看了我的简历就和我约了第二天的面试。电脑也没带,晚上就用手机复习了前端的一些…...