织梦网站安装,做多语言网站多少钱,windows 2008 搭建网站,什么是网络推广工作首先导入依赖#xff1a;
dependencies:
pigeon: ^10.0.0定义一个文件#xff1a;
/// 用于定于flutter和平台的桥接方法
/// HostApi() 标记的#xff0c;是用于 Flutter 调用原生的方法#xff1b;
/// FlutterApi() 标记的#xff0c;是用于原生调用 Flutter 的方法
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;MapString?, Object?? arguments;
}
class ApiParams {String? url;MapString?, 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至原生页面参数页面名称、参数
Futurevoid pushNativePage(CommonParams arg_params) async {final BasicMessageChannelObject? channel BasicMessageChannelObject?(dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.pushNativePage, codec,binaryMessenger: _binaryMessenger);final ListObject?? replyList await channel.send(Object?[arg_params]) as ListObject??;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: (ResultString?) - 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: MessageCodecAny? 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 BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.pushNativePage, codec)if (api ! null) {channel.setMessageHandler { message, reply -val args message as ListAny?val paramsArg args[0] as CommonParamsvar wrapped: ListAny?try {api.pushNativePage(paramsArg)wrapped listOfAny?(null)} catch (exception: Throwable) {wrapped wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.popPage, codec)if (api ! null) {channel.setMessageHandler { message, reply -val args message as ListAny?val paramsArg args[0] as CommonParams?var wrapped: ListAny?try {api.popPage(paramsArg)wrapped listOfAny?(null)} catch (exception: Throwable) {wrapped wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.requestNativeApi, codec)if (api ! null) {channel.setMessageHandler { message, reply -val args message as ListAny?val apiParamsArg args[0] as ApiParamsapi.requestNativeApi(apiParamsArg) { result: ResultString? -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 BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.enablePopRecognizer, codec)if (api ! null) {channel.setMessageHandler { message, reply -val args message as ListAny?val enableArg args[0] as Booleanvar wrapped: ListAny?try {api.enablePopRecognizer(enableArg)wrapped listOfAny?(null)} catch (exception: Throwable) {wrapped wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.showToast, codec)if (api ! null) {channel.setMessageHandler { message, reply -val args message as ListAny?val typeArg AppType.ofRaw(args[0] as Int)!!val msgArg args[1] as Stringvar wrapped: ListAny?try {api.showToast(typeArg, msgArg)wrapped listOfAny?(null)} catch (exception: Throwable) {wrapped wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.showLoading, codec)if (api ! null) {channel.setMessageHandler { message, reply -val args message as ListAny?val showArg args[0] as Booleanval typeArg AppType.ofRaw(args[1] as Int)!!val msgArg args[2] as String?var wrapped: ListAny?try {api.showLoading(showArg, typeArg, msgArg)wrapped listOfAny?(null)} catch (exception: Throwable) {wrapped wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}run {val channel BasicMessageChannelAny?(binaryMessenger, dev.flutter.pigeon.isolarcloud_flutter.SGHostApi.getUserInfo, codec)if (api ! null) {channel.setMessageHandler { _, reply -var wrapped: ListAny?try {wrapped listOfAny?(api.getUserInfo())} catch (exception: Throwable) {wrapped wrapError(exception)}reply.reply(wrapped)}} else {channel.setMessageHandler(null)}}}}
}同步或者异步的去调用自动生成的方法
Futurevoid 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}?psId1234)}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: (ResultMapAny, 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: ResultMapAny, Any? Result.success(mapOf(name to outputStream),)callback(result)*/val map: MutableMapString, Any HttpRequest.getCommonParamMap()HttpUtil.postWithPath(/v1/devService/getDevModelUpgradeConfigList, /*apiParams.arguments*/map, object : HttpGlobalHandlerCallbackUpdateRequestBean?() {override fun onSuccess(jsonResult: JsonResultsUpdateRequestBean?) {// 处理成功返回的数据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(): MapAny, Any? {val map mutableMapOfAny, 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: ResultMapAny, Any? Result.success(// mapOf(// name to John,// age to 30,// email to johnexample.com// )// )// callback(result)// 通过callback返回错误信息val failureResult: ResultMapAny, Any? Result.failure(Exception(An error occurred))callback(failureResult)}override fun onFinish() {super.onFinish()}})}override fun disablePopRecognizer(disable: Boolean) {}}}在flutter中统一使用这个类来获取原生获取的网络数据
/// 成功回调
typedef SuccessCallback void Function(MapString, dynamic? resultData, String resultCode, String resultMsg);/// 失败回调
typedef ErrorCallback void Function();class RequireNativeApi {static void postWithPathOversea(String? url, MapString?, Object?? arguments,SuccessCallback? successCallback, ErrorCallback? errorCallback,{bool showToast true}) {postWithPath(url, arguments, successCallback, errorCallback,showToast: showToast, appType: AppType.oversea);}static void postWithPathDomestic(String? url,MapString?, Object?? arguments,SuccessCallback? successCallback,ErrorCallback? errorCallback,{bool showToast true}) {postWithPath(url, arguments, successCallback, errorCallback,showToast: showToast, appType: AppType.domestic);}static void postWithPath(String? url, MapString?, 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;MapString, Object argument {};var cache await JsonCacheManageUtils.getCacheData(JsonCacheManageUtils.HomeMessageResponse,labelId: labelStr.toString()).then((value) {if (value ! null) {return HomeMsgEntity.fromJson(value as MapString, 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(MapString, 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();MapString, dynamic argument {is_all: 1,message_scene_code: messageSceneCode,};RequireNativeApi.postWithPathOversea(Api.getUpdateUserMessage, argument,getClearMessageSuccess, () SGOSLoadingToast.dismissLoading());}void getClearMessageSuccess(MapString, 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();MapString, dynamic argument {ids: ids,message_scene_code: messageSceneCode,};state.removeIndex index;RequireNativeApi.postWithPathOversea(Api.getDeleteUserMessage, argument,getDeleteMessageSuccess, () SGOSLoadingToast.dismissLoading());}void getDeleteMessageSuccess(MapString, 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(ListHomeMsgPageList 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;}MapString, dynamic argument {ids: null,message_scene_code: result,};RequireNativeApi.postWithPathOversea(Api.getDeleteUserMessage, argument,getDeleteMessageSuccess, () SGOSLoadingToast.dismissLoading());}
}按理来说这个GetxController类是用来访问网络的类这里用来和原生交互就这样子。
最近工作忙加班重疏于思考缺乏输出望大家理解有时间优化文章敬请期待