zycloudMain function

void zycloudMain({
  1. required bool debug,
  2. required String appname,
  3. required String dbname,
  4. required String dbpwd,
  5. required String bsid,
  6. required String secret,
  7. required EasyClientConfig config,
  8. required bool service,
  9. EasyClientConfig? clientConfig,
  10. String? docNativeUpgradeUrl,
  11. String? docUserAgreementUrl,
  12. String? docPrivacyPolicyUrl,
  13. String? ringMessagesTickUrl,
  14. String? ringRealtimeCallUrl,
  15. String? ringRealtimeWaitUrl,
  16. String agentFlag = 'ZyCloud',
  17. bool fetchCodeLocalServer = false,
  18. String fetchCodeLocalBaseUrl = 'http://127.0.0.1:8888',
  19. void initSystemChromeStyles()?,
  20. void initAppCustomPages()?,
  21. dynamic nativeValueConverter(
    1. dynamic value
    )?,
  22. String? quickTypeSpeculationMethod(
    1. dynamic instance
    )?,
  23. Widget remoteCodeLoadingBuilder({
    1. int? count,
    2. int? total,
    })?,
})

ZyCloud程序快捷启动入口

  • debug 调式环境
  • appname 应用名称
  • dbname 应用数据库名称
  • dbpwd 应用数据库密码
  • bsid 云服务商户标识
  • secret 云服务商户密钥
  • config 云服务网络配置
  • service 云服务是否启用
  • clientConfig 应用网络客户端自定义配置信息,本SDK内仅读取,完全自定义用途
  • docNativeUpgradeUrl 应用更新页面
  • docUserAgreementUrl 用户协议页面
  • docPrivacyPolicyUrl 隐私政策页面
  • ringMessagesTickUrl 新消息提示音
  • ringRealtimeCallUrl 来电呼叫铃声
  • ringRealtimeWaitUrl 来电等待铃声
  • agentFlag 设备的agentFlag标志
  • fetchCodeLocalServer 强制从本地服务器加载代码
  • fetchCodeLocalBaseUrl 强制从本地服务器加载代码时的根路径
  • initSystemChromeStyles 初始化设备系统风格的方法
  • initAppCustomPages 初始化自定义模块的方法
  • nativeValueConverter 对虚拟机中的迭代类型默认转换的方法
  • quickTypeSpeculationMethod 加快虚拟机中类型名查找的方法
  • remoteCodeLoadingBuilder 拉取远程代码时的进度界面
  • remoteCodeLoadingLogo 拉取远程代码时的默认进度界面的logo

Implementation

void zycloudMain({
  required bool debug,
  required String appname,
  required String dbname,
  required String dbpwd,
  required String bsid,
  required String secret,
  required EasyClientConfig config,
  required bool service,
  EasyClientConfig? clientConfig,
  String? docNativeUpgradeUrl,
  String? docUserAgreementUrl,
  String? docPrivacyPolicyUrl,
  String? ringMessagesTickUrl,
  String? ringRealtimeCallUrl,
  String? ringRealtimeWaitUrl,
  String agentFlag = 'ZyCloud',
  bool fetchCodeLocalServer = false,
  String fetchCodeLocalBaseUrl = 'http://127.0.0.1:8888',
  void Function()? initSystemChromeStyles,
  void Function()? initAppCustomPages,
  dynamic Function(dynamic value)? nativeValueConverter,
  String? Function(dynamic instance)? quickTypeSpeculationMethod,
  Widget Function({int? total, int? count})? remoteCodeLoadingBuilder,
  Widget? remoteCodeLoadingLogo,
}) async {
  ///确保库加载完毕
  WidgetsFlutterBinding.ensureInitialized();

  ///初始化屏幕样式
  if (initSystemChromeStyles == null) {
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); //模式边缘方式
    SystemChrome.setPreferredOrientations(<DeviceOrientation>[DeviceOrientation.portraitUp]); //固定屏幕方向
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark.copyWith(statusBarColor: Colors.transparent)); //状态栏透明
  } else {
    initSystemChromeStyles();
  }

  ///初始化设备信息
  await ZyDeviceInfo.init(agentFlag: agentFlag);

  ///加载虚拟机类库
  EasyVmWare.loadGlobalLibrary(
    globalLogger: EasyLogger(logTag: '${ZyDeviceInfo.deviceType.name}-VmWare', logger: ZyApp.bestConsoleLogger),
    coreClassList: ZyBridge.coreClassList,
    coreProxyList: ZyBridge.coreProxyList,
    userClassList: ZyBridge.userClassList,
    userProxyList: ZyBridge.userProxyList,
    nativeValueConverter: (value) {
      //自定义的转换
      final result = nativeValueConverter == null ? null : nativeValueConverter(value);
      if (result != null) return result;
      //转换数据类型 => anyKeys: <ObjectId>[]
      if (value is List<ObjectId>) return value;
      if (value is List && value.isNotEmpty && value.first is ObjectId) return value.cast<ObjectId>();
      //转换数据类型 => children: <InlineSpan>[]
      if (value is List<InlineSpan>) return value;
      if (value is List && value.isNotEmpty && value.first is InlineSpan) return value.cast<InlineSpan>();
      //转换数据类型 => items: <BottomNavigationBarItem>[]
      if (value is List<BottomNavigationBarItem>) return value;
      if (value is List && value.isNotEmpty && value.first is BottomNavigationBarItem) return value.cast<BottomNavigationBarItem>();
      //转换数据类型 => items: <DropdownMenuItem>[]
      if (value is List<DropdownMenuItem>) return value;
      if (value is List && value.isNotEmpty && value.first is DropdownMenuItem) return value.cast<DropdownMenuItem>();
      //转换数据类型 => children: <Widget>[]
      if (value is List<Widget>) return value;
      if (value is List && value.isNotEmpty && value.first is Widget) return value.cast<Widget>();
      //转换数据类型 => builders: <TargetPlatform, PageTransitionsBuilder>{}
      if (value is Map<TargetPlatform, PageTransitionsBuilder>) return value;
      if (value is Map && value.isNotEmpty && value.keys.first is TargetPlatform && value.values.first is PageTransitionsBuilder) return value.cast<TargetPlatform, PageTransitionsBuilder>();
      //转换数据类型 => MaterialStatePropertyAll<Color>
      if (value is MaterialStatePropertyAll<Color>) return value;
      if (value is MaterialStatePropertyAll && value.value is Color) return MaterialStateProperty.all<Color>(value.value); //这个创建了副本
      //转换数据类型 => AlwaysStoppedAnimation<double>
      if (value is AlwaysStoppedAnimation<double>) return value;
      if (value is AlwaysStoppedAnimation && value.value is double) return AlwaysStoppedAnimation<double>(value.value); //这个创建了副本
      return value;
    },
    quickTypeSpeculationMethod: (instance) {
      //custom
      final result = quickTypeSpeculationMethod == null ? null : quickTypeSpeculationMethod(instance);
      if (result != null) return result;
      //flutter
      if (instance is Size) return 'Size'; //_DebugSize
      if (instance is Path) return 'Path'; //_NativePath
      if (instance is Canvas) return 'Canvas'; //_NativeCanvas
      if (instance is FormFieldState) return 'FormFieldState'; //_TextFormFieldState
      if (instance is RenderObjectElement) return 'RenderObjectElement'; //_LayoutBuilderElement<BoxConstraints>
      //webrtc
      final typeName = VmObject.readRuntimeClassName(instance);
      if (typeName == 'MediaDeviceNative') return 'MediaDevices';
      if (typeName == 'MediaStreamNative') return 'MediaStream';
      if (typeName == 'MediaStreamTrackNative') return 'MediaStreamTrack';
      if (typeName == 'RTCPeerConnectionNative') return 'RTCPeerConnection';
      //webview
      if (typeName == 'AndroidWebResourceError' || typeName == 'WebKitWebResourceError') return 'WebResourceError';
      return null;
    },
  );

  ///加载静态的定制
  if (initAppCustomPages != null) initAppCustomPages();

  runApp(
    ZyApp(
      logLevel: debug ? EasyLogLevel.debug : EasyLogLevel.warn,
      logLifecycle: debug,
      logRouteStack: debug,
      localAppBuilder: () => App.start(
        debug: debug,
        appname: appname,
        dbname: dbname,
        dbpwd: dbpwd,
        bsid: bsid,
        secret: secret,
        config: config,
        service: service,
        splash: remoteCodeLoadingBuilder == null ? _RemoteCodeLoading(logo: remoteCodeLoadingLogo) : remoteCodeLoadingBuilder(),
        clientConfig: clientConfig,
        docNativeUpgradeUrl: docNativeUpgradeUrl,
        docUserAgreementUrl: docUserAgreementUrl,
        docPrivacyPolicyUrl: docPrivacyPolicyUrl,
        ringMessagesTickUrl: ringMessagesTickUrl,
        ringRealtimeCallUrl: ringRealtimeCallUrl,
        ringRealtimeWaitUrl: ringRealtimeWaitUrl,
      ),
      remoteAppBuilder: EasyVmWare(
        config: EasyVmWareConfig(
          logger: ZyApp.bestConsoleLogger,
          logLevel: debug ? EasyLogLevel.debug : EasyLogLevel.warn,
          logTag: '${ZyDeviceInfo.deviceType.name}-VmWare',
          mainMethod: 'App.start',
          mainNameArgs: {
            #debug: debug,
            #appname: appname,
            #dbname: dbname,
            #dbpwd: dbpwd,
            #bsid: bsid,
            #secret: secret,
            #config: config,
            #service: service,
            #splash: remoteCodeLoadingBuilder == null ? _RemoteCodeLoading(logo: remoteCodeLoadingLogo) : remoteCodeLoadingBuilder(),
            #clientConfig: clientConfig,
            #docNativeUpgradeUrl: docNativeUpgradeUrl,
            #docUserAgreementUrl: docUserAgreementUrl,
            #docPrivacyPolicyUrl: docPrivacyPolicyUrl,
            #ringMessagesTickUrl: ringMessagesTickUrl,
            #ringRealtimeCallUrl: ringRealtimeCallUrl,
            #ringRealtimeWaitUrl: ringRealtimeWaitUrl,
          },
        ),
      ),
      remoteCodeLoading: (total, count) => remoteCodeLoadingBuilder == null
          ? _RemoteCodeLoading(
              total: total,
              count: count,
              logo: remoteCodeLoadingLogo,
            )
          : remoteCodeLoadingBuilder(
              total: total,
              count: count,
            ),
      remoteCodeFetcher: (processReport) async {
        if (ZyDeviceInfo.isWeb) return null; //web环境无需代码推送
        if (fetchCodeLocalServer) {
          //获取manifest的信息
          final manifest = utf8.decode((await EasyClient.get('$fetchCodeLocalBaseUrl/manifest')).bodyBytes); //直接拉取调试服务器托管的最新版本的codefiles
          //拉取最新版本dart文件
          final codefiles = jsonDecode(manifest) as List;
          final codebodys = <String, String>{};
          processReport(codefiles.length, 0); //初始化进度条
          for (var i = 0; i < codefiles.length; i++) {
            final item = codefiles[i] as String;
            codebodys[item] = utf8.decode((await EasyClient.get('$fetchCodeLocalBaseUrl$item')).bodyBytes); //分别拉取每一份源代码文件
            processReport(codefiles.length, i + 1); //更新进度条
          }
          return codebodys.isNotEmpty ? codebodys : null;
        } else if (service) {
          //获取manifest的信息
          final client = NetClient(
            config: EasyClientConfig.fromSourceAndArgs(
              source: config,
              logger: ZyApp.bestConsoleLogger,
              logLevel: EasyLogLevel.warn,
              logTag: '${ZyDeviceInfo.deviceType.name}-Fetcher',
            ),
            bsid: bsid,
            secret: secret,
            isolate: !ZyDeviceInfo.isWeb,
            onCredentials: (user, credentials) {},
          );
          final manifest = await client.appManifest(codefiles: true); //不指定codeVersion即拉取最新版本的codefiles
          if (!manifest.ok) return null; //加载错误
          if (ZyDeviceInfo.devicePackge.intBuildNumber >= client.business.version) return null; //已经是最新版本
          if (ZyDeviceInfo.devicePackge.intBuildNumber < client.business.minsdkv) return null; //不支持远程版本
          //拉取最新版本dart文件
          final codefiles = manifest.extra!;
          final codebodys = <String, String>{};
          processReport(codefiles.length, 0); //初始化进度条
          for (var i = 0; i < codefiles.length; i++) {
            final item = codefiles[i];
            final itemResult = await client.appCodeFile(id: item.id);
            if (itemResult.ok) {
              codebodys[item.name] = itemResult.extra!.content;
              processReport(codefiles.length, i + 1); //更新进度条
            } else {
              return null; //加载错误
            }
          }
          return codebodys.isNotEmpty ? codebodys : null;
        } else {
          return null;
        }
      },
    ),
  );
}