干货 | 携程APP Native/RN内嵌Flutter UI混合开发实践和探索

RN + Flutter 1 RN简介 1 全称: RN == React Native 2 文档地址: https://www.react-native.cn/ 3 作用: 专门用于做 App 的 (IOS / Android) 4 使用场景: 技术实力较好的公司, (需要 React 的开发水平) 5 RN 环境搭建: 方式 1: 简易沙盒环境 (国内基本用不了) 方式 2: 完整原生环境 (安装依赖: Node、JDK 和 Android Studio) 2 Flutter简介 1 作用: 专门用于做 A 阅读详情

作者简介

 

Deway,携程资深工程师,iOS客户端开发,热衷于大前端和动态化技术;

Frank,携程高级工程师,关注移动端热门技术,安卓客户端开发。

前言

随着各种多端技术的蓬勃发展,如今的移动端和前端早已不再拘泥于自身的边界,而是不断延伸、扩展和融合,逐步向着真正的大前端技术迈进。跨端技术也从早期的Cordova/PhoneGap、纯H5页面发展到如今的ReactNative(以下简称RN)、Weex、小程序、Flutter群雄并存的局面。各种技术栈各有优劣和特点,技术选型需视团队自身情况而定,没有绝对好坏之分。然而在实际开发中,并不是只选用一种技术栈,那么研究多种技术栈融合和嵌套使用的就有了迫切的必要性。

本文我们从实际业务场景出发,初步实践了在RN里面嵌套flutter view、在native里面嵌套flutter view,探索其可行性,并回顾这个过程中遇到的一些问题和解决方案。

一、背景

1.1 现状

随着时间的推移,携程app中酒店列表和详情两大页面已经全部转为flutter技术栈,初期的使用场景也比较单一,只在主流程使用。然而业务不断迭代之后,flutter页面在其他流程使用的频次也越来越高,比如列表页面,作为酒店一线SKU产品展示的主页面,复用的需求非常旺盛和迫切。那么此时需要思考更多的通用性和可移植性,以适用于在不同的场景不同的技术栈页面嵌入使用。

1.2 两大场景

1de24e26ea4df9e48b9b380c5da0693a.png

bca782b5cf90cb450a2dc5d592be2b40.png

  • 场景一:上左图为携程大搜页面的酒店列表。在本次技术改造之前,大搜页面的酒店列表和酒店主流程的列表大相径庭,差异不光是在UI展示方面,酒店频道列表的信息和优惠更加完整,价格体系也更统一。大搜的技术栈是RN,而酒店列表技术栈是flutter,如果想要统一无非两种途径:1)查漏补缺追平RN侧业务;2)将flutter酒店列表打包嵌入RN页面。

  • 场景二:上右图为查询页钟点房标签下的钟点房列表,查询页目前还是native技术栈,那么此时也必须考虑将flutter列表页嵌入native页面。

对于不同技术栈的业务场景,不断为多侧业务同步补齐功能,维护成本是相当巨大的。对于酒店列表业务来说,唯一可选的路径就是在大搜和酒店主频道等业务场景中共用一个列表,甩开历史包袱,实现真正意义上的业务对齐。所以,基于以上两个场景,我们初步探索了flutter页面在多种复杂结构的嵌套使用,即RN中嵌套flutter、原生ListView中嵌套flutter,并将解决方案记录在本文中,为之后可能遇到的多业务场景提供一个思路。

二、RN中使用Flutter

2.1 可行方案的探究

在接到这个嵌套需求的时候,考虑到成本最低的方式是直接在大搜页面层上盖列表,即在切换到酒店tab的时候将flutter view盖在上层。实际上在思考利弊之后,放弃了这个方案。有如下几个弊端:

  • RN无法单独控制flutter view层的展示, 需要通过层层事件通知,复杂且繁琐

  • RN需要计算出上盖offset的偏移值,在不同屏幕尺寸存在偏差

  • 在不同tab切换的时候,flutter控制器生命周期难以及时被同步

基于上述的几个问题,那么考虑的方向就偏向于直接把flutter view包装成RN的Component使用。

2.2 Native Components的原理

我们先简单回顾下RN的启动流程(以iOS为例)。

b4d8ac908b3f2acf8a5657dee0b55431.png

RN启动流程

  • 程序启动完成的时候创建了根视图RCTRootView,负责展示所见内容的根容器

  • 创建管理native和js的交互的桥接对象RCTBridge

  • 创建RCTBatchedBridge批量桥对象, 这个类是负责交互通信的核心

  • 加载所有自定义的native modules。这些modules最终会被转为RCTModuleData类型,包含方法列表、队列等信息,并缓存到全局的模块配置信息表中

  • 通过jsExecutor将native创建的模块表注册到js端

  • 开始异步加载js代码,执行完成后通知到RCTUIManager去调用对应的native组件进行渲染

这里省去了一些非关键步骤,可以看到RN本身是支持调用native原生组件的,调用native UI components这一步比较关键的是RCT_EXPORT_MODULE。这是一个宏定义,重写了load方法,在其中调用RCTRegisterModule方法。再看看RCTRegisterModule的实现,其实就是将moduleClass注册到一个全局容器。

/// iOS
#define RCT_EXPORT_MODULE(js_name)          \
  RCT_EXTERN void RCTRegisterModule(Class); \
  +(NSString *)moduleName                   \
  {                                         \
    return @ #js_name;                      \
  }                                         \
  +(void)load                               \
  {                                         \
    RCTRegisterModule(self);                \
  }
/// iOS
void RCTRegisterModule(Class moduleClass)
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    RCTModuleClasses = [NSMutableArray new];
    RCTModuleClassesSyncQueue =
        dispatch_queue_create("com.facebook.react.ModuleClassesSyncQueue", DISPATCH_QUEUE_CONCURRENT);
  });


  RCTAssert(
      [moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
      @"%@ does not conform to the RCTBridgeModule protocol",
      moduleClass);


  // Register module
  dispatch_barrier_async(RCTModuleClassesSyncQueue, ^{
    [RCTModuleClasses addObject:moduleClass];
  });
}

moduleClass注册完之后什么时候使用呢?接下来就到RCTCxxBridge的start方法, 将所有注册的组件放入moduleClasses,并将继承于RCTViewManager的module单独拿出来再处理。

/// iOS
(void)[self _initializeModules:RCTGetModuleClasses() withDispatchGroup:prepareBridge lazilyDiscovered:NO];
/// iOS
  _componentDataByName = [NSMutableDictionary new];
  for (Class moduleClass in _bridge.moduleClasses) {
    if ([moduleClass isSubclassOfClass:[RCTViewManager class]]) {
      RCTComponentData *componentData = [[RCTComponentData alloc] initWithManagerClass:moduleClass bridge:_bridge];
      _componentDataByName[componentData.name] = componentData;
    }
  }

从头到尾来理解下,在main函数开始执行之前,将申明为RCT_EXPORT_MODULE的组件注册到全局容器中,并在bridge中生成RCTViewManager对应的RCTComponentData对象,并配置moduleConfig的模块信息表(上述步骤4中完成)。然后在RCTUIManager中建立和js布局层的对应关系,最后在js层进行计算、排版之后通过UIManager.js通知到native层的RCTUIManager进行渲染绘制。这就是一个RN使用Native原生组件的原理和过程,由此可以见RN对于modules层的设计具备高度可扩展性和伸缩性。

2.3 前置条件

2.3.1 组件生命周期

携程主站是一个包含native、RN、H5、flutter技术栈的混合app,基础框架由native代码实现,因此flutter业务需要依赖于兼容native、flutter的技术框架,业内比较成熟的解决方案是FlutterBoost。

FlutterBoost的理念是将flutter像Webview那样来使用,通过native容器来管理flutter页面。类似的,携程app中RN技术栈也是一个RN-native混合方案CRN,用native容器封装了RN页面。这样的方案可以实现一个native容器中同时嵌套native、RN、flutter组件,并由native容器管理生命周期。

那flutter-RN组件嵌套时,如何实现不同组件生命周期相关联?由于目前列表flutter view是依附列表控制器存在的,在创建RN对应的列表控制器view时,将flutter view的控制器挂载到父控制器,这样实现了flutter view依赖RN的生命周期,伪代码如下。

// iOS
 UIViewController *rootVC = (UIViewController *)[self currentVisibleViewController];
 [rootVC addChildViewController:flutterViewControler];

从官方手册可知,

This method creates a parent-child relationship between the current view controller and the object in the childController parameter. This relationship is necessary when embedding the child view controller’s view into the current view controller’s content. If the new child view controller is already the child of a container view controller, it is removed from that container before being added.

Android的实现类似,从xml文件可以看出,同样是将flutter view挂载到RN父ViewGroup中,即RNLinearLayout。

<!-- Android -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.list.RNLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <com.android.list.RNFrameLayout
       android:id="@+id/flutter_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
</com.android.list.RNLinearLayout>

小结一下,flutter的生命周期可以依赖于嵌入的父组件,如下表所示。

父组件

子组件

生命周期依赖对象

RN

Flutter

RN

Native

Flutter

Native

2.3.2 flutter页面启动方式

由FlutterBoost官方文档可知,flutter页面以路由的方式启动,携程app中实现(以Android为例)如下代码段所示。启动时需配置一个flutter url,包含页面类型、业务参数、UI相关参数等,用一个fragment来管理view,并在fragment的生命周期不同阶段完成flutter初始化、绘制、销毁等操作,伪代码如下。

/// Android
val flutterFragment = new FlutterFragment
        .CachedEngineFragmentBuilder(FlutterFragment.class, FlutterBoost.ENGINE_ID)
        .flutterURL(mFlutterURL)
        .build();
fragmentTransaction.add(R.id.fragment_stub, flutterFragment).commitNowAllowingStateLoss();

2.4 开始

从前述原理来看,native的UI组件直接遵守RCTViewManager的模式提供view方法就可以被RN调用。那么是不是flutter view的嵌入也可以遵从这套范式呢?顺着这个思路设计结构图如下:

4c653272a5953bd39b98bb36ff30b612.png

rnFlutter混合结构图

  • RNTListManager继承于RCTViewManager,负责提供view给RN,设置和更新视图的属性,并接受RN传递过来的事件,比如目的地关键字、入离日期以及业务埋点数据。

  • FlutterEmbedderPlugin,统一处理flutter view的创建、回收、销毁以及与之相关的事件回调。之后需要增加业务场景时,那么创建其子类处理具体业务就行。

  • GlobalSearchEmbedderPlugin作为FlutterEmbedderPlugin子类,负责处理具体场景下的业务,提供RNTListManager需要的视图。

js层包装类如下:

/// RN伪代码
class RNFlutterView extends PureComponent {
    componentDidMount() {
         const {keyword} = this.props;
            let data = { keyword: keyword};
            UIManager.dispatchViewManagerCommand(
                findNodeHandle(this),
                UIManager.FlutterListView.Commands.callFlutterEmbedderMethod, 
                [data]
            );
    }


    /*..... 省略了无关的业务代码 */


    render() {
          return <FlutterListView style={{width: screenWidth}}
        />
     }


     componentWillUnmount() {
       /// 页面消失的时候回调flutterEmbedder
        UIManager.dispatchViewManagerCommand(
            findNodeHandle(this),
            UIManager.FlutterListView.Commands.disposeView, 
            null
          );
     }
}
const FlutterListView = requireNativeComponent('FlutterListView', RNFlutterView);


export default RNFlutterView;

下面罗列主体结构的部分代码。iOS的实现部分伪代码如下:

/// iOS
/// RNTListManager
RCT_EXPORT_MODULE(FlutterListView)


- (UIView *)view {
    if (self.viewPlugin == nil) {
        self.viewPlugin = [[GlobalSearchEmbedderPlugin alloc] init];
        [self.viewPlugin createView];
    }
    return self.viewPlugin.exportView;
}


RCT_EXPORT_METHOD(setDestinationParam:(nonnull NSNumber *)reactTag param:(NSDictionary *)paramDict) {
    [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
        UIView *view = (UIView*)viewRegistry[reactTag];
        if (view) {
            [self.viewPlugin setDestinationData:paramDict];
        }
    }];
}


RCT_EXPORT_METHOD(disposeView:(nonnull NSNumber *)reactTag) {
    [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
        UIView *view = (UIView*)viewRegistry[reactTag];
        if (view) {
            [self.viewPlugin disposeView];
        }
    }];
}
/// iOS
@interface GlobalSearchEmbedderPlugin : FlutterEmbedderPlugin


- (void)createView;


- (void)setDestinationData:(NSDictionary *)param;


@end


@implementation GlobalSearchEmbedderPlugin


- (void)createView {
    if (self.listVC == nil) {


        [self initListViewController];


        [self bindCacheData];


        /* listVC挂载到UIViewController, 生命周期保持一致*/
        UIViewController *rootVC = (UIViewController *)[self currentVisibleViewController];
        [rootVC addChildViewController:self.listVC];
    }
}


- (void)setDestinationData:(NSDictionary *)param {
    /// 省略业务代码部分


    [self.listVC sendSerivce];
}


@end

Android平台上对于flutter view嵌入RN容器有相似的流程。首先需要在RN初始化时创建ViewReactPackage,它会提供给RN一个RNViewManager,伪代码如下:

/// Android
class GlobalSearchEmbedderPlugin : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule> {
        return ArrayList()
    }


    override fun createViewManagers(reactContext: ReactApplicationContext): MutableList<SimpleViewManager<*>> {
        val result = ArrayList<SimpleViewManager<*>>()
        val listManager = RNViewManager()
        result.add(listManager)
        return result
    }
}

RNViewManager在RN里注册嵌入native模块的名字、layout、RN和native通信接口实现。native模块的名字需要与RN中的RCT_EXPORT_MODULE名字、iOS native模块的名字对应。command接口实现了相关业务逻辑,比如initFlutterFragment()方法中创建flutter view,其它command接口中实现了目的地关键字、入离日期以及业务埋点数据等等。

/// Android
class RNTListManager : SimpleViewManager<RNLinearLayout>() {
    companion object {
        const val COMMAND_SET = 1
    }


    override fun getName(): String {
        return "FlutterListView"
    }


    override fun createViewInstance(reactContext: ThemedReactContext): RNLinearLayout {
        return LayoutInflater.from(reactContext)
            .inflate(R.layout.flutter_container, null) as RNLinearLayout
    }


    override fun getCommandsMap(): MutableMap<String, Int> {
        return MapBuilder.of(
            "setDestinationParam", COMMAND_SET,
        )
    }


    override fun receiveCommand(root: RNLinearLayout, commandId: String?, args: ReadableArray?) {
        when (commandId?.toInt()) {
            COMMAND_SET -> initFlutterFragment(root.context, args)
        }
    }
}

RN native layout有一些特殊,由于flutter view自身是一个framelayout,RN native layout定义为一个子view是framelayout的linearlayout,这样可以实现动态地在RN native viewGroup中加入flutter view。根据官方文档,RN native view需要覆写requestLayout()方法,并在方法中重新做测量和布局,伪代码如下:

/// Android
public class RNLinearLayout extends LinearLayout {
    public RNLinearLayout(Context context) {
        super(context);
    }


    public RNLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    public RNLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    private final Runnable measureAndLayout = () -> {
        measure(
                MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
        layout(getLeft(), getTop(), getRight(), getBottom());
    };


    @Override
    public void requestLayout() {
        super.requestLayout();
        post(measureAndLayout);
    }
}

考虑到flutter view并不是单一场景使用,比如上述1.2节的场景二,需要在酒店查询页移植列表页。最终的结构设计如下图,Native层对应具体的业务创建对应的EmbedderPlugin,负责处理相关的事件,flutter层在不同路由下对应具体的page。

15aae0fd7f9e747838a337cead3ded8d.png

flutterEmbedder结构

三、Native嵌套Flutter

3.1 可行方案的探究

从view树的角度,RN嵌套flutter的实现和native嵌套flutter的实现是一致的。RN嵌套flutter时,flutter view作为一个view group加入到RN container中,而native嵌套flutter时,flutter view作为一个view group直接加入到native view树中。这样的实现需要考虑四个要点:点击事件传递、view启动顺序、flutter层与native层的业务交互、页面的生命周期。

3.2 方案实现

3.2.1 点击事件传递

处理点击事件传递,flutter view作为一颗view子树,能够直接接受到从上到下传递的点击事件。点击事件传递过程如下左图所示,在flutter点击区域由flutter处理事件,若flutter不处理则回到父view处理。

2ae85e01aedf988649f98906951d64bb.png 

flutter点击事件

e61bc86326d734f3d9a8299640a11d2e.png

flutter滑动事件

list滚动事件则需要在flutter view子树的祖先view中进行适当屏蔽,确保flutter列表能嵌套滚动。本次实现的业务场景是1.2节中的场景二,在一个native滚动列表最下方嵌入flutter滚动列表,flutter滚动列表正好能占满一个屏幕。整个列表向下滚动过程中,先滚动外层列表,当滚动到底部时滚动flutter列表;反之,整个列表向上滚动过程中,先滚动flutter列表,当flutter列表滚动到头部时滚动,向上滚动外层列表。

如上图所示,滑动过程(1)是flutter列表可滑动场景,需要将事件返回外层列表;滑动过程(2)是列表可滑动场景;滑动过程(3)是flutter列表不可上滑,而外层列表可上滑场景,此时需要将事件传递到外层列表使其上滑,这个过程中会有顿挫感,我们在实现中给外层列表添加了滑动效果进行补偿。

3.2.2 view启动顺序

通常是先创建native view树,在view树创建成功后,手动创建flutter view并加入view树中。手动创建flutter view可以根据业务需要,以懒加载的方式创建。在app启动之后,不管是否启动flutter view,都需要先初始化flutter引擎。

3.2.3 flutter-native业务交互

业务在flutter层与native层的交互,主要通过flutter method channel,在native层预先注册method channel和各种事件,在flutter view启动之后由flutter层或native层双向发送消息。

3.2.4 页面的生命周期

生命周期已在2.3.1节中详细描述,可以由native层容器或者flutter view来控制,通常是根据业务所占页面比例决定,我们的实现中是将flutter view包在一个native容器中,这样可以用相同的方法在native控制生命周期。

四、写在最后

至此我们初步探索了不同技术栈UI的嵌套,为之后的组件的复用提供了一套切实可行的实践依据。后续会在此基础上做进一步的优化,比如flutter view的滚动事件如何很平滑地传输到native,使得双列表嵌套滚动的时候没有顿挫感。在实践中,随着组件复杂度的和依赖度升高,混合的改造成本也是逐步增加的,那么是否需要混合、如何轻量化的移植也是需要进一步衡量和思考的。

参考文献

团队招聘信息

我们是携程酒店前端研发团队,负责携程Ctrip APP/国际版Trip APP/小程序/Web端的酒店业务研发和创新。保障酒店业务高效产出,稳定迭代的同时,持续优化用户体验和优化酒店预订流程。

在酒店前端研发团队,有包容性,多样性的团队文化,你可以和一群纯真,富有激情的年轻人一起工作,为全球旅行者的提升旅行体验。

如果你热爱技术,并渴望不断成长,携程酒店前端研发团队期待您的加入。目前我们Android/IOS/RN/Flutter/H5/服务等领域均有开放职位。简历投递邮箱:tech@ctrip.com,邮件标题:【姓名】-【携程酒店前端】-【投递职位】。

【推荐阅读】

645eb9ff624db892f2fa239a3b85c544.png

 “携程技术”公众号

  分享,交流,成长

干货 | 携程机票 React Native 整洁架构实践 作者简介任跃华, 携程机票前台软件工程师,从事机票android、react和react native技术栈相关研发工作。前言携程机票前台团队在使用 React Nati... 阅读详情

相关推荐

YOLOv5s模型训练全流程解析:从数据准备到实战检测

本文详细解析了YOLOv5s模型训练的全流程,涵盖从环境搭建、数据准备与格式转换,到模型训练、参数调优及实战检测的完整步骤。文章提供了具体的代码示例和常见问题解决方案,旨在帮助开发者,特别是新手,高效掌握YOLOv5s模型训练的核心技术,并成功应用于实际检测任务中。

weixin_29041767的博客 332

android原生接入rn,Android原生项目集成ReactNative

Mac下搭建ReactNative开发环境一文中讲过了如何搭建环境以及创建一个ReactNative项目,很多时候我们会在原生项目开发中集成ReactNative,我们该怎么做呢?下面我们一步步实现吧。1.打开终端进入原生项目的根目录,输入npm init命令执行的过程中会让你填写一系列的值如下图所示:npm.jpg上面name属性填写的是reactnativedemo,最后输入yes结束,最终会...

weixin_30748139的博客 538

2026年4月AI爆发周:阿里连推三款模型、字节全双工语音上线,国内大模型进入“落地竞速“新阶段

**摘要:**2026年4月初,国内AI大模型迎来密集发布,阿里、字节、腾讯分别推出新产品。阿里一周发布三款模型,覆盖通用推理、多模态轻量化和长文档处理,API价格大幅下降;字节推出全双工语音模型,实现实时交互,技术难度高;腾讯混元3.0强调工程化和生态整合,面向企业私有化部署。趋势显示,行业从性能竞赛转向落地竞赛,多模态成为主战场,API成本降低,开发者选择更丰富。国内大模型竞争重点转向实际应用和生态整合。

weixin_45526015的博客 1万+

iOS开发嵌套ReactNative页面

最近使用ReactNative做项目,有信心今天目标把ReactNative框架掌握,所以自己从每个知识点学习提高自己吧...... 步骤如下: 一.创建依赖包文件(package.json): React Native的植入过程同时需要React和React Native两个node依赖包。我们把具体的依赖包记录在package.json文件中。 如果项目根目录中没有这个文件,那就自...

weixin_30677073的博客 188

道闸不自动落杆故障排查:从传感器原理到控制器调试全解析

在工业自动化和物联网系统中,传感器与控制器构成的闭环控制是保障设备可靠运行的核心。其基本原理是通过传感器采集环境状态,控制器依据预设逻辑做出决策并驱动执行器动作。这一技术价值在于实现了无人值守下的安全、高效自动化,广泛应用于智能交通、安防和智能楼宇等领域。以停车场道闸系统为例,其自动落杆功能高度依赖地感线圈与防砸雷达的协同。地感线圈作为触发单元,负责感知车辆接近;而防砸雷达则作为持续监测的安全单元,通过微波探测防砸区域内是否有障碍物,其信号是控制器执行落杆决策的关键依据。当系统出现车辆通过后闸杆不落的典型故

weixin_29190651的博客 311

iperf3网络性能测试全攻略:从带宽到丢包率的实战技巧

本文提供了iperf3网络性能测试的完整实战指南,涵盖从基础部署到高级诊断的全流程。详细解析了TCP带宽测试的进阶技巧与UDP丢包率分析的深度方法,帮助网络工程师精准量化带宽、丢包率等关键指标,有效定位网络瓶颈并优化性能。

efc123456的博客 1018

React Native 三端同构在雪球的实践

React Native Web 由前 Twitter 前端主管 Necolas 开发,并使用该技术方案在 2017 年重构了 Twitter 网页 (Twitter Web App) 并沿用至今。React Native Web 在国内知名度不高,但是放眼世界 Twitter Web、Expo、NativeBase、React Native 官网等众多项目全部使用的 React Native Web 能力。

小王的技术库 1925

CAD制图

CAD制图可以提高设计效率和准确性,并方便文档的存档和交流,是现代工程设计中不可或缺的一部分。·CAD三维开发是指使用计算机程序和工具来创建、编辑和操作三维模型、图形和设计的过程。它在工程、建筑、制造和游戏等领域广泛应用。CAD三维开发可能涉及到复杂的图形算法、性能优化、并行计算等方面的内容,因此需要深入学习和实践,以提高开发的效率和质量。

RZer的博客 1649

RN-app的基础框架

react-navigation5.x新实践目录前言react-navigation5.xcreateBottomTabNavigator (@react-navigation/bottom-tabs)

qq_37938547的博客 1432

ESP32-CAM入门教程

ArduinoESP32-CAM下载模块(接上USB就能用,很方便,如果没有买就只有资金用USB-TTL了)如下图两个合在一起如下图。

qq_48778364的博客 3万+

24、汽车黑客技术全解析:诊断代码、车库创建与系统攻防

本文深入探讨了汽车黑客技术的核心内容,包括诊断代码模式与参数ID、创建开放车库社区、汽车系统相关技术、硬件与软件工具、攻击与防御手段,以及车辆通信与网络安全。无论你是汽车安全研究人员、爱好者还是开发者,都能从中获取全面的技术解析与实践指南。

Apple的专栏 226

干货 | 携程机票RN复杂交互实践

作者简介海涛,携程前端开发工程师,负责机票主流程预订、React Native技术栈相关开发工作。前言本文将主要介绍在携程中文APP国内机票模块中,对往返机票的预定流程改造期间,在Re...

携程技术 1703

通过Simulink搭建一个智能微电网能量管理系统(Energy Management System, EMS)

通过上述代码实现,您可以逐步创建一个智能微电网能量管理系统。多源能量集成:整合光伏、风力发电、柴油发电机、电池储能等多种能源资源。负荷预测与调度:基于历史数据和天气预报,预测未来负荷和可再生能源输出,进行优化调度。储能系统优化:设计合理的充放电策略,确保储能系统的高效利用和寿命延长。经济性分析:评估不同运行模式下的经济性,考虑电价、维护成本等因素。环境影响评估:分析微电网对环境的影响,如减少碳排放、提高可再生能源利用率等。硬件在环仿真(HILS)

amy_mhd的博客 314

React Native技术栈学习路径

大致了解了一下RN的实现,感觉里面的技术栈是比较深的,跟搞前端的大牛请教了一下,大致总结出下面一个学习路径,决定按部就班把这方面技术好好学习一下。

lihei12345的专栏 4009

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

RN技术在转转的落地与实践 (前端篇)

RN异常错误的归纳、分级以便于进行对应的兜底处理, 形成体系化方案;虽然AI不能完全替代开发者进行思考和决策,但作为一个强大的辅助工具,它能够将开发者从大量重复、模式化的代码转换工作中解放出来,让我们更专注于架构设计、性能优化和业务逻辑的实现,最终以更低的成本、更快的速度完成技术栈的现代化迁移。在转换过程中, 先将依赖组件库的原子组件转换完成并验证各个原子组件的可用性, 再以转换后的原子组件作为上下文知识库进一步转换业务页面的组件, 再次验证业务组件的可用性,可大大提高转换后整个业务项目的代码可用性.

大转转FE 1344

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

2024年前端最全React技术栈 --》搭建与实操 ## Day1,大佬推荐

中年危机是真实存在的,即便有技术傍身,还是难免对自己的生存能力产生质疑和焦虑,这些年职业发展,一直在寻求消除焦虑的依靠。技术要深入到什么程度?做久了技术总要转型管理?我能做什么,我想做什么?一技之长,就是深耕你的专业技能,你的专业技术。(重点)独立做事,当你的一技之长达到一定深度的时候,需要开始思考如何独立做事。(创业)拥有事业,选择一份使命,带领团队实现它。(创业)一技之长分五个层次栈内技术 - 是指你的前端专业领域技术栈外技术 - 是指栈内技术的上下游,领域外的相关专业知识。

2401_84619245的博客 1919

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

React Native 开发心得分享

有一段时间没更新了,花了点时间研究了下 React Native(后续用 RN 简称),同时也用该技术作为我的毕设项目(一个校园社交应用,仿小红书),经过了这段时间的疯狂折腾,对 RN 生态有了一定的了解,我想是时候可以分享点一些东西了。

kuizuo12的博客 1507

大前端突围之路:从RN跨平台到大前端全栈统一

大前端当下内卷愈演愈烈,各种技术风起云涌,无数小伙伴感慨「别学了,跟不上了!」。在我们身边也经常会看到各种焦虑,不管是做移动端开发的,还是做前端开发的,都在卷与被卷的过程中,而这中卷似乎进入到一种畸形的状态,就是比谁会的技术多。在招聘中经常会看到在简历专业技能一栏写满一排,从安卓到IOS,从前端到后段。但是真的问起来,都是浅尝辄止。所以我们不禁要问:真的需要一个人会那么多技术吗?

mukewangguanfang的博客 631

RN实现混合式开发-内嵌html

React Native WebView是一个用于在React Native应用中嵌入Web内容的组件。它允许你在应用中显示网页、加载HTML字符串、运行JavaScript代码等。

weixin_38441229的博客 2159

RN:app开发入门指南

这篇文章主要带大家了解一下 app 开发的一个流程,方便后续想要做 app 的同学了解学习,接下来我会以一个前端的视角介绍 app 开发的一些情况~ 学习路线 js: React17:app 开发基础语言 React Native(RN):app 跨端开发方案 TypeScript(TS):强类型 JavaScript mobx-state-tree(MST):状态管理库 ignite:脚手架 android: java:android 开发语言 Maven:包管理工具 Gradle:构建工具 adb:调

分享前端开发工程师的一些日常生活、前端知识点、职业发展、对一些问题的看法、感悟等等 2184

移动端开发(原生、H5、React Native、Flutter)

一、现有APP技术栈 现有APP使用原生、RN、H5技术栈 原生:首页、一级页面,主要考虑性能优 RN:二级页面,功能稳定的页面 H5:活动页面(有分享功能)、功能变动比较多的页面 原生提供桥接接口给RN使用 客户端提供桥接接口给H5使用 二、原生、React Native、Flutter技术对比 技术 性能 开发效率 渲染方式 学习成本 可扩展性 Flutter 高,接近原生体验 高 Skia高性能自绘引擎 低,Widget组件化 高,采用插件化的库进行扩展 RN/Weex/小程序 有

u014340331的博客 3602

React Native 开发总结

前言   2015年3月, Facebook正式发布react-native,只支持iOS平台;2015年9月,Facebook发布了React Native for Android,让这一技术正式成为跨平台开发框架。   我们团队是在2016年中期开始接触并使用react-native, 起初团队有很多反对声,其中   iOS平台严格的审核制度,还有后来的JSPatch风波,担心...

qq_39581763的博客 355

flutter与原生交互_Native 集成 Flutter 及通信交互最详教程

前不久开源了用Flutter开发的一个音视频类App客户端,欢迎大家star, fork。⚠️ 项目地址:https://github.com/songxiaoliang/visitor-flutter⚠️ 本篇博客涉及的源码全部开源在Github,地址:https://github.com/songxiaoliang/flutter-android-hybrid目前现有的跨平台开发解决...

weixin_34749183的博客 537

开源推荐 | 携程 Foxpage 前端低代码框架

作者简介Jason Wang,携程研发经理,目前主要负责低代码类产品的设计和研发,关注低代码行业的发展及相关解决方案在企业内部的落地。大厂技术高级前端Node进阶点击上方程序员成长指北,关注公众号回复1,加入高级Node交流群源码地址:https://github.com/foxpage?sort=stargazers一、背景随着低代码开发方式被越来越多的人接...

程序员成长指北 1014

Flutter与RN

Flutter是谷歌的移动UI框架,可以快速的在IOS和Android上构建高质量的原生用户界面,Flutter可以与现有的代码一起工作,且开源免费Flutter用于创建高性能,跨平台的移动应用框架,针对于当下以及未来的移动设备进行优化,专注于Android和IOS低延迟的输入和高帧率Flutter的设计跟react native很像,但是比RN进一步Flutter的开发语言是Dart1. 性能方面:Flutter由于是基于Dart语言, 所以避免了RN的那种通过桥接器与Javascript通讯导致效率低下

Ai1114的博客 3万+

将网站打包成桌面程序并生成安装包(跨平台)

若想将网站封装为系统的可执行文件并生成安装包,首先可以通过Nativefier将网站打包成可执行文件,然后再使用Qt Installer Framework将可执行文件及相关数据生成系统安装包文件

XiaoChen10086的博客 4556
上一篇: 干货 | 数据思维在携程商旅页面性能优化中的一次实践
下一篇: 干货 | 携程商旅订单系统架构设计和优化实践
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值