native 订阅
native是一个计算机函数,一个Native Method就是一个Java调用非Java代码的接口。方法的实现由非Java语言实现,比如C或C++。 展开全文
native是一个计算机函数,一个Native Method就是一个Java调用非Java代码的接口。方法的实现由非Java语言实现,比如C或C++。
信息
外文名
native
类    型
计算机术语
中文名
原生方法
软    件
Java
nativeNative Method(原生方法)
"A native method is a Java method whose implementation is provided by non-java code." [1]  在定义一个native method时,并不提供实现体(有些像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的。下面给了一个示例:这些方法的声明描述了一些非Java代码在这些Java代码里看起来像什么样子(view).标识符native可以与所有其它的java标识符连用,但是abstract除外。这是合理的,因为native暗示这些方法是有实现体的,只不过这些实现体是非java的,但是abstract却显然的指明这些方法无实现体。native与其它java标识符连用时,其意义同非Native Method并无差别,比如native static表明这个方法可以在不产生类的实例时直接调用,这非常方便,比如当你想用一个native method去调用一个C的类库时。上面的第三个方法用到了native synchronized,JVM在进入这个方法的实现体之前会执行同步锁机制(就像java的多线程。)一个native method方法可以返回任何java类型,包括非基本类型,而且同样可以进行异常控制。这些方法的实现体可以制一个异常并且将其抛出,这一点与java的方法非常相似。当一个native method接收到一些非基本类型时如Object或一个整型数组时,这个方法可以访问这些非基本型的内部,但是这将使这个native方法依赖于你所访问的java类的实现。有一点要牢牢记住:我们可以在一个native method的本地实现中访问所有的java特性,但是这要依赖于你所访问的java特性的实现,而且这样做远远不如在java语言中使用那些特性方便和容易。native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法。JVM将控制调用本地方法的所有细节。需要注意当我们将一个本地方法声明为final的情况。用java实现的方法体在被编译时可能会因为内联而产生效率上的提升。但是一个native final方法是否也能获得这样的好处却是值得怀疑的,但是这只是一个代码优化方面的问题,对功能实现没有影响。如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用java语言重写这个方法(这个似乎看起来有些奇怪),同样的如果一个本地方法被final标识,它被继承后不能被重写。本地方法非常有用,因为它有效地扩充了JVM。事实上,我们所写的Java代码已经用到了本地方法,在Sun的Java的并发(多线程)的机制实现中,许多与操作系统的接触点都用到了本地方法,这使得java程序能够超越Java运行时的界限。有了本地方法,Java程序可以做任何应用层次的任务。
收起全文
精华内容
参与话题
问答
  • 完全征服React Native

    万人学习 2016-08-22 11:47:32
    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识...
  • React Native运行原理解析

    万次阅读 多人点赞 2016-09-22 15:54:18
    Facebook 于2015年9月15日推出react native for Android 版本, 加上2014年底已经开源的IOS版本,至此RN (react-native)真正成为跨平台的客户端框架。本篇主要是从分析代码入手,探讨一下RN在安卓平台上是如何构建...

    Facebook 于2015年9月15日推出react native for Android 版本, 加上2014年底已经开源的IOS版本,至此RN (react-native)真正成为跨平台的客户端框架。本篇主要是从分析代码入手,探讨一下RN在安卓平台上是如何构建一套JS的运行框架。

    一、 整体架构

    RN 这套框架让 JS开发者可以大部分使用JS代码就可以构建一个跨平台APP。 Facebook官方说法是learn once, run everywhere, 即在Android 、 IOS、 Browser各个平台,程序画UI和写逻辑的方式都大致相同。因为JS 可以动态加载,从而理论上可以做到write once, run everywhere, 当然要做额外的适配处理。如图:

    _1
    RN需要一个JS的运行环境, 在IOS上直接使用内置的javascriptcore, 在Android 则使用webkit.org官方开源的jsc.so。 此外还集成了其他开源组件,如fresco图片组件,okhttp网络组件等。

    RN 会把应用的JS代码(包括依赖的framework)编译成一个js文件(一般命名为index.android.bundle), , RN的整体框架目标就是为了解释运行这个js 脚本文件,如果是js 扩展的API, 则直接通过bridge调用native方法; 如果是UI界面, 则映射到virtual DOM这个虚拟的JS数据结构中,通过bridge 传递到native , 然后根据数据属性设置各个对应的真实native的View。 bridge是一种JS 和 JAVA代码通信的机制, 用bridge函数传入对方module 和 method即可得到异步回调的结果。

    对于JS开发者来说, 画UI只需要画到virtual DOM 中,不需要特别关心具体的平台, 还是原来的单线程开发,还是原来HTML 组装UI(JSX),还是原来的样式模型(部分兼容 )。RN的界面处理除了实现View 增删改查的接口之外,还自定义一套样式表达CSSLayout,这套CSSLayout也是跨平台实现。 RN 拥有画UI的跨平台能力,主要是加入Virtual DOM编程模型,该方法一方面可以照顾到JS开发者在html DOM的部分传承, 让JS 开发者可以用类似DOM编程模型就可以开发原生APP , 另一方面则可以让Virtual DOM适配实现到各个平台,实现跨平台的能力,并且为未来增加更多的想象空间, 比如react-cavas, react-openGL。而实际上react-native也是从react-js演变而来。

    对于 Android 开发者来说, RN是一个普通的安卓程序加上一堆事件响应, 事件来源主要是JS的命令。主要有二个线程,UI main thread, JS thread。 UI thread创建一个APP的事件循环后,就挂在looper等待事件 , 事件驱动各自的对象执行命令。 JS thread 运行的脚本相当于底层数据采集器, 不断上传数据,转化成UI 事件, 通过bridge转发到UI thread, 从而改变真实的View。 后面再深一层发现, UI main thread 跟 JS thread更像是CS 模型,JS thread更像服务端, UI main thread是客户端, UI main thread 不断询问JS thread并且请求数据,如果数据有变,则更新UI界面。

    二、 代码流程

    1、JS入口

    _2015_10_26_4_40_39

    对于JS开发者来说, 整个RN APP就只有一个JS文件, 而开发者需要编写的就只有如上部分。主要是四个部分:

    • require 所有依赖到的组件, 相当于java中的import 或者 c++ 中的include。

    • var AwesomeProject = React.createClass 创建APP, 并且在render函数中返回UI界面结构(采用JSX ), 实际经过编译, 都会变成JS 代码, 比如 变成 React.createElement(View,{style:{flex:1}},

    • var styles = StyleSheet.create({, 创建CSS 样式,实际上会直接当做参数直接反馈到上面的React.createElement

    • AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject); 以上三个更像是参数,这个才是JS 程序的入口。即把当前APP的对象注册到AppRegistry组件中, AppRegistry组件是js module。

    接着就等待Native事件驱动渲染JS端定义的APP组件。

    2、Native 入口

    _2015_10_26_5_01_52

    对于Android 开发者, 普通安卓程序入口是Activity.onCreate()方法 , 主要有三个对象

    • ReactRootView, Android 标准的FrameLayout对象,另外一个功能是提供react 世界的入口,函数startReactApplication实际调用attachMeasuredRootView触发react世界的初始化。

    • MyReactPackage, 配置当前APP 需要加载的模块,RN 的JS框架会在初始化阶段就会把native的模块按照配置加载到JS数据结构中(MessageQueue), 从而才能在JS 层即可直接判断native是否支持某个模块。支持三种类型模块配置, native module(实际就是不需要操作View结构的API), view managers(实际是映射到virtual DOM中的View组件), JS module 。

    • ReactInstanceManager, 构建React世界的运行环境,发送事件到JS世界, 驱动整个React世界运转。 通过builder可以创建不同的React环境, 比如内置js 路径, 开发环境dev的js名字,是否支持调试等。doInBackground会加载指定的JS文件, onPostExecute会调用runApplication接口运行JS APP。
      _2015_10_27_8_02_04

    ReactRootView第一次onMeasured计算完成, 然后会利用ReactInstanceManager创建 ReactContext上下文环境。重要的是初始化bridge以及加载js文件, 利用JSBundleLoader方法加载index.android.bundle. 如图

    _2015_10_27_1_41_19

    此刻进入JS 世界, 开发者的js 语句连同react js框架层被执行。该步骤最终语句是执行AppRegistry.registerComponent注册一个APP组件,但还没有到开始渲染。

    当运行环境准备完毕, 则调用bridge方法运行上步注册的APP组件,触发一连串JS 和 Native相互通信,配合事件驱动, 从而完成native世界的渲染。如图利用bridge方法运行上面注册的JS APP组件的runApplication方法: 
    _2015_10_27_1_37_35

    3、事件循环

    所有的APP在操作系统中, 最终都会使用一个事件循环来运行。

    一般来说,JS 开发者只需要开发各个组件对象,监听组件事件, 然后利用framework接口调用render方法渲染组件。

    而实际上,JS 也是单线程事件循环,不管是 API调用, virtural DOM同步, 还是系统事件监听, 都是异步事件,采用Observer(观察者)模式监听JAVA层事件, JAVA层会把JS 关心的事件通过bridge直接使用javascriptCore的接口执行固定的脚本, 比如"requrire (test_module).test_methode(test_args)"。此时,UI main thread相当于work thread, 把系统事件或者用户事件往JS层抛,同时,JS 层也不断调用模块API或者UI组件 , 驱动JAVA层完成实际的View渲染。JS开发者只需要监听JS层framework定义的事件即可。如图即JS thread 的消息队列循环:

    _2015_10_27_10_13_36

    分析代码可知,消息线程创建于ReactContext环境初始化时, MessageQueueThread.java当中, 该消息队列主要接收系统事件(如 Vsync、timer、doFrame、backkey)、UI事件(如键盘弹起、滚动等)以及 callback事件(JS 的回调函数)。
    如图即ReactRootView往JS 传递键盘弹出的事件:

    _2015_10_27_11_20_27

    而对于Android 开发者, Android 已经为APP创建一个默认的 Main Looper, 不管是Android System 还是JS 事件都是发送到Main thread通过UI渲染出来。如图即是MessageQueueThread.java直接使用主线程Looper。

    _2015_10_27_11_08_11

    跟普通APP不同是,此时JS thread相当于work thread, JS会把对应的事件或者数据通过bridge发送到UI thread。 如图即是native Java层收到的JS事件的处理函数:
    _2015_10_27_1_47_12

    三、 通信机制

    RN框架最主要的就是实现了一套JAVA和 JS通信的方案,该方案可以做到比较简便的互调对方的接口。一般的JS运行环境是直接扩展JS接口,然后JS通过扩展接口发送信息到主线程。但RN的通信的实现机制是单向调用,Native线程定期向JS线程拉取数据, 然后转成JS的调用预期,最后转交给Native对应的调用模块。这样最终同样也可以达到Java和 JS 定义的Module互相调用的目的。

    1、JS调用java

    JS调用java 使用通过扩展模块require('NativeModules')获取native模块,然后直接调用native公开的方法,比如require('NativeModules').UIManager.manageChildren()。 JS 调用require('NativeModules')实际上是获取MessageQueue里面的一个native模块列表的属性, 如:
    _2015_10_27_4_03_35

    _2015_10_27_2_00_49

    使用_genModules 加载所有native module到 RemoteModules数组。RemoteModules每项都是一个映射到native module的JS对象。

    _2015_10_27_4_08_02

    调用RemoteModules 的方法, 实际是把moduleID、methodId、args放入三个queue保存。

    _2015_10_27_4_10_34

    至此, JS端调用完毕, queue中数据要等待Native层通过bridge来取。

    native层会在一定条件下触发事件, 通过bridge调用callFunctionReturnFlushedQueue
    和 invokeCallbackAndReturnFlushedQueue ,得到的返回值就是这三个queue。

    _2015_10_27_4_39_12

    bridge会把这三个queue交给parseMethodCalls解析, 然后通过JNI回调函数转发到Java层
    _2015_10_27_4_42_17

    m_callback 函数是在bridge初始化的时候设置到c++层, 如:
    _2015_10_27_4_45_02

    然后在回调函数中,陆续调用ReactCallback对象的call方法,weakCallback就是java层初始化bridge时传入的NativeModulesReactCallback对象,也就是ReactCallback的子类。

    _2015_10_27_4_53_41

    到此,转入Java层. 从native module配置表中,取到对应module和method,并执行。
    _2015_10_27_4_58_22

    2、java调用JS

    之前ReactInstanceManager 中运行JS APP组件,JAVA 是调用catalystInstance.getJSModule 方法获取JS 对象,然后直接访问对象方法runApplication。实际上getJSModule 返回的是js对象在java层的映射对象。

    java层可以调用的JS模块主要在CoreModulesPackage.createJSModules方法配置,有:

    _2015_10_27_4_23_46

    如果调用JSModules对象的方法,则会动态代理跳转到(mBridge).callFunction(moduleId, methodId, arguments);

    _2015_10_27_4_27_15

    接着调用ReactBridge中声明的JNI 函数,
    public native void callFunction(int moduleId, int methodId, NativeArray arguments);

    _2015_10_27_4_31_32

    _2015_10_27_5_01_42

    通过JS 的require和 apply函数拼接一段JS 代码, 然后用javascriptCore的脚本运行接口执行,并得到返回值。

    _2015_10_27_5_03_09

    这样就在JS引擎中运行了一段JS代码并得到返回值,实现了JAVA层到JS层的调用。每次有JAVA对JS的访问, 则在返回值中从JS层的messageQueue.js中抓取之前累积的一堆JS calls。因为JAVA层要把时间同步、 系统帧绘制等事件传递给JS, 因此queue中的JS calls都会在很短的时间内被抓取。

    四、 扩展机制

    1、 模块扩展(native module)
    官方文档操作:
    https://facebook.github.io/react-native/docs/native-modules-android.html#content

    2、 组件扩展(UI component)
    官方文档操作:
    https://facebook.github.io/react-native/docs/native-components-android.html#content

    因为react模块加载主要在ReactPackage类配置,因此扩展可以通过反射、外部依赖注入等机制,可以做到跟H5容器一样实现动态插拔的插件式扩展。比如API扩展, 通过外部传入扩展模块的类名即可反射构造函数创建新的API:

        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            List<NativeModule> modules = new ArrayList();
            modules.addAll(Arrays.<NativeModule>asList(
                    new AsyncStorageModule(reactContext),
                    new FrescoModule(reactContext),
                    new NetworkingModule(reactContext),
                    new WebSocketModule(reactContext),
                    new ToastModule(reactContext)));
            if (mModuleList != null && mModuleList.size() > 0) {
                for (int i = 0; i < mModuleList.size(); i++) {
                    try {
                        Log.i("MyReactPackage", "add Module:" + mModuleList.get(i));
                        Class c = Class.forName(mModuleList.get(i));
                        Class[] parameterTypes = {ReactApplicationContext.class};
                        java.lang.reflect.Constructor constructor = c.getConstructor(parameterTypes);
                        Object[] parameters = {reactContext};
                        NativeModule module = (NativeModule) constructor.newInstance(parameters);
                        modules.add(module);
                    }catch (Exception e) {
                        Log.i("MyReactPackage", "add Module Exeception:" + e);
                        e.printStackTrace();
                    }
                }
            }
            return modules;
        }
    

    五、 离线加载

    代码离线

    • 离线包支持。 目前RN官方支持内置APK打包以及dev server在线更新。而实际上,一般的容器都会实现一套离线包发布平台。大致的实现方案是自定义一个JSBundleLoader,对接到应用管理发布平台。
      _2015_10_27_6_02_57

    • 分离react 框架代码和应用业务代码。目前官方的生产工具是把框架代码和业务代码弄成一个bundle。 但框架代码很大,需要共用, 因此要分离出框架代码单独前置加载。 应用业务代码变成很小一段JS代码单独发布。如果每次都加载框架代码, 启动业务代码会比较慢,一个helloworld都需要4秒左右。初步实践方案是把ReactInstanceManager设置成全局变量共享,在Native APP 启动初始化或者第一次进入RN APP时初始化ReactInstanceManager。这个可能会导致多个RN APP全局变量冲突。

    • 在线更新
      离线包更新主要依赖应用管理发布平台,大致可以做到跟H5离线包一致。

    资源离线

    一般说的是图片资源比较多, RN 使用控件显示图片,如:
    _2015_10_27_5_43_26

    通过source属性设置图片资源路径, 映射到native层:
    _2015_10_27_5_46_33

    _2015_10_27_5_46_52

    因此不管是离线包内资源还是系统资源,只要能转换成Android 统一资源定位URI对象,即可获取到图片。

    在线资源

    如果是静态资源,则直接URI统一定位。如果是动态资源, 比如要通过网关获取到base64格式的图片,则需要native扩展特别接口。

    六、 总结

    1、 可能瓶颈

    *   因为bridge,  JS和 JAVA是异步互通,如果实现复杂多API的逻辑,可能会导致部分效率损耗在多线程通信。JS 异步的编程方式多多少少带来一些不便。
    *  因为bridge,  可能某些场景做不到及时响应。比如帧动画的实时控制。
    *  Android版本刚推出不完善,并且目前RN版本还在不停的更新中, 可能存在暗坑。
    *  加入JS引擎, 内存的控制比较麻烦,会比普通native增加不少。
    

    2、 待研究

    • 动态注入的API插件实现方案,能跟h5容器共用实现。
    • 因为RN已经具备很多的灵活, JS也可以做到很多大型控件,所以native UI扩展需要定义JS 和 native边界, 哪些是JS 实现, 哪些是native实现。
    • 动画的实现方式。
    • H5容器和RN容器融合方案
    • write once, 完全跨平台。
    • JS 层支持 Fragment manager

    性能比较数据

    • Demo还在实现当中,等抓完再补充。

    环境搭建

    展开全文
  • React Native初级入门到项目实战

    万人学习 2016-10-13 13:52:46
    ReactNative是由Facebook公司发布的可以进行混合开发的开源技术框架。通过ReactNative可以为iOS和Android两个系统开发应用程序,“Learn once,write anywhere”。使用ReactNative开发,既拥有Native的良好人机交互...
  • 解决办法:Failed to load the native TensorFlow runtime.

    万次阅读 多人点赞 2018-10-09 09:56:17
    跑CPU版的object-detection的示例程序,导入tensorflow时...Failed to load the native TensorFlow runtime. 解决办法就是:pip install --upgrade --ignore-installed tensorflow 更新一下tensorflow就好了 ...

    跑CPU版的object-detection的示例程序,导入tensorflow时出现:

    Failed to load the native TensorFlow runtime.

    解决办法就是:pip install --upgrade --ignore-installed tensorflow

    更新到最新版本的tensorflow就好了

    展开全文
  • H5、React NativeNative应用对比分析

    万次阅读 多人点赞 2016-06-24 01:09:37
    摘要 2015年是React Native发展的一年,2016年必定是React Native蓬勃的一年!2016年React Native很可能成为最为成功的开源技术之一。为什么React Native这么火呢?那么React Native相比H5、Native又有哪些优势呢?...

    @王利华,vczero

    “存在即合理”。凡是存在的,都是合乎规律的。任何新事物的产生总要的它的道理;任何新事物的发展总是有着取代旧事物的能力。React Native来的正是时候,一则是因为H5发展到一定程度的受限;二则是移动市场的迅速崛起强调团队快速响应和迭代;三则是用户的体验被放大,用户要求极致的快感,除非你牛x(例如:12306最近修改手机号需要用户自己发短信接收验证码)。
    以下简单的介绍下H5、React Native、Native的含义:

    最近三四年间,国内外的前端与全栈开发者社区都在坚持不懈地追寻使用JavaScript与HTML、CSS技术体系开发App内场景的核心工程技术。这种技术,在国内很多公司与团队中,被通称为H5。——童遥

    这段是取自童老师给小二我新书作的序,没有断章取义的意思。很清楚,H5并不是狭义的HTML5新标签和API,而是工程化的“In App” technology。

    iOS/Android ——原生应用(都懂得,不解释)。

    React Native —— React & Native ,应运而生!

    一、React Native的出现

    React Native的出现,似乎是扛起的反H5的旗子。就像当年Facebook放弃H5,全部转向Native一样。这一点,我们需要认同和保持高度的清醒。那么,React Native是否又是在吞食Native的领地呢?技术的发展,是用户风向标的导向起的作用。任何一门技术的出现,都是当时用户需求的体现。

    我们应该从以下几点看待React Native的出现。

    "鉴往知来"——从过去的教训中总结经验,从用户的角度开拓未来
    “HTML5差强人意,但是与原生应用相比还是有些差距”——为了更高的追求! 用户体验!
    “人才宝贵,快速迭代”——Web开发者相对较多,寻找平衡点
    “跨平台!跨平台!跨平台!”——单一技术栈
    “xx是世界上最好的语言” ——工程学的范畴,没有最好,只有最适合

    HTML5 vs React Native ? HTML5 : React Native
    结论(React Native):
    1、原生应用的用户体验
    2、跨平台特性
    3、开发人员单一技术栈
    4、上手快,入门容易
    5、社区繁荣

    二、3款应用效果

    注:以下所有对比均在iOS平台下



    上面3张图片,如果去掉第一张图的“HybirdApp”的字样,是否分得清哪个是React Native开发?哪个是Native应用。
    你的第一感觉是什么?

    三、工程方案

    为了评估3种方案的技术优势和弱势。我们需要开发功能大致相似的App。这里,我们使用了“豆瓣”的API来开发“豆搜”应用。该应用能够搜索“图书”、“音乐”、“电影”。想当年,豆瓣以“图书评论”走红,尤其是12年当红!豆瓣是一个清新文艺的社区,一个“慢公司”。最近有一则网传消息,注意是网传——“传京东投1.5亿美元控股豆瓣”。今天,不聊豆瓣,我们要聊一个工程化的问题。

    我们需要将3款App的功能做到一致,同时需要保持技术要点一致。比如React Native这里使用了TabBar,那么Native我们也必须使用TabBar。简单而言就是:功能一致,组件 & API一致。我们功能如下图所示:

    1、H5方案
    在H5/Hybird应用中,我们使用AngularJS开发单页webApp,然后将该WebApp内嵌入到iOS WebView中,在iOS代码中,我们使用Navigation稍微控制下跳转。
    WebApp地址:http://vczero.github.io/search/html/index.html
    WebApp项目地址:https://github.com/vczero/search (很简单的一个项目)
    H5/Hybird项目地址:https://github.com/vczero/search_Hybird

    2、React Native
    在React Native中,封装必要的功能组件。
    项目地址:https://github.com/vczero/React-Dou。
    项目结构如下图:

    3、Native(iOS)
    使用React Native大致相同的组件开发App,不使用任何第三方库,代码布局。
    项目地址:https://github.com/vczero/iOS-Dou

    四、对比分析

    很多时候,新技术的采用最希望看到的是数据,而不是简单说“用户体验棒,开发效率高,维护成本低”。不过,生活中也有这样的同学,知一二而能窥全貌。当然,本人生性胆小,也没有那么多的表哥和隔壁的老王,所以不敢早下定论,不敢太放肆。赵本山在《大笑江湖》中有句名言“May the force be with you”(别太放肆,没什么用)。因此,从以下几个方面做一个简单的对比。

    ----------提纲------------

    1、开发方式

    (1)代码结构
    (2)UI布局
    (3)UI截面图
    (4)路由/Navigation
    (5)第三方生态链

    2、性能 & 体验

    (1)内存
    (2)CPU
    (3)动画
    (4)安装包体积
    (5)Big ListView
    (6)真机体验

    3、更新 & 维护

    (1)更新能力
    (2)维护成本
    ----------提纲------------

    1、开发方式

    很多人说React Native的代码不好看,不好理解。那是因为前端工程师都熟悉了Web的开发方式。怎么解决这个问题呢,可以先看看iOS代码,断定不熟悉iOS的同学心里会默念“一万匹**马奔腾”。那时候,你再看React Native,你会觉得使用React Native开发App是件多么美好的事!OK,我们先来看下三者在开始“一款简单App”的代码结构。
    (1)代码结构
    H5/Hybird的开发模式,我们需要维护3套代码,两套是Native(iOS/Android)代码,一套是WebApp版本。这里,我们使用AngularJS作为WebApp单页开发框架。如下图所示。

    在React Native中,同样需要关注部分的Native代码,但是大部分还是前端熟悉的JavaScript。在“豆搜”应用中,代码结构如下:

    在Native开发中,更加强调Native开发者的能力。平台是:iOS/Android。

    结论:从前端角度而言,React Native跨平台特性,不要开发者深入的了解各平台就能开发一款高效App。同时,语言层面而言,JavaScript运用很广泛,入门门槛相对较低。React Native虽然抛弃了MVC分离实践,但是从业务角度而言,更为合理。一切而言:对前端,对移动领域是利好的消息。

    (2)UI布局
    “面容姣好”,合理的UI却总是跟着时间在变。那么UI布局就不是小事。
    Web开发布局目前大多是 DIV + CSS。
    React Native的布局方式是Flexbox。

       //JSX
      <ScrollView style={styles.flex_1}>
        <View style={[styles.search, styles.row]}>
          <View style={styles.flex_1}>
            <Search placeholder="请输入图书的名称" onChangeText={this._changeText}/>
          </View>
          <TouchableOpacity style={styles.btn} onPress={this._search}>
            <Text style={styles.fontFFF}>搜索</Text>
          </TouchableOpacity>
        </View>
        {
          this.state.show ?
          <ListView
            dataSource={this.state.dataSource}
            renderRow={this._renderRow}
            />
          : Util.loading
        }
      </ScrollView>
      //样式
      var styles = StyleSheet.create({
          flex_1:{
            flex:1,
            marginTop:5
          },
          search:{
            paddingLeft:5,
            paddingRight:5,
            height:45
          },
          btn:{
            width:50,
            backgroundColor:'#0091FF',
            justifyContent:'center',
            alignItems:'center'
          },
          fontFFF:{
            color:'#fff'
          },
          row:{
            flexDirection:'row'
          }
        });        

    而Native布局就有种让你想吐的感觉,尤其是iOS的布局。这里不是指采用xib或者Storyboard,而是单纯的代码,例如添加一个文本:

    UILabel *publisher = [[UILabel alloc]init];
    publisher.frame = CGRectMake(bookImgWidth + 10, 50, 200, 30);
    publisher.textColor = [UIColor colorWithRed:0.400 green:0.400 blue:0.435 alpha:1];
    publisher.font = [UIFont fontWithName:@"Heiti TC" size:13];
    publisher.text = obj[@"publisher"];
    [item addSubview:publisher];           

    总结:React Native既综合了Web布局的优势,采用了FlexBox和JSX,又使用了Native原生组件。比如我们使用一个文本组件。
    <Text style={{width:100;height:30;backgroundColor:'red'}}>测试</Text>

    (3)UI截面图
    Hybrid方式截面图

    可以看到第一层列表页是完整的布局,实际上这就是Web页面;而第二层灰色的是Native的WebView组件。
    iOS UI截面图


    可以看到Native页面的组件特别多,即使是列表页,其中某一项都是一个组件(控件)。

    当然,我们就会想,能够完全调用原生组件呢?那样性能是否更好?
    React Native UI截面图


    可以清楚的看到React Native调用的全部是Native组件。并且层次更深,因为React Native做了组件的封装。如上图,蓝色边框的就是RCTScrollView组件。

    (4)路由/Navigation
    在Web单页面应用中,路由由History API实现。
    而React Native采用的路由是原生的UINavigationController导航控制器实现。
    React Native NavigatorIOS组件封装程度高;Navigator可定制化程度高。
    Navigator方法如下:

    getCurrentRoutes() - returns the current list of routes
    jumpBack() - Jump backward without unmounting the current scene
    jumpForward() - Jump forward to the next scene in the route stack
    jumpTo(route) - Transition to an existing scene without unmounting
    push(route) - Navigate forward to a new scene, squashing any scenes that you could jumpForward to
    pop() - Transition back and unmount the current scene
    replace(route) - Replace the current scene with a new route
    replaceAtIndex(route, index) - Replace a scene as specified by an index
    replacePrevious(route) - Replace the previous scene
    immediatelyResetRouteStack(routeStack) - Reset every scene with an array of routes
    popToRoute(route) - Pop to a particular scene, as specified by its route. All scenes after it will be unmounted
    popToTop() - Pop to the first scene in the stack, unmounting every other scene         

    相对Native而言,这些接口更Native还是很相似的。

    //iOS UINavigationController  
    //相对Web而言,不用自己去实现路由,并且路由更加清晰         
    [self.navigationController pushViewController:detail animated:YES];

    "豆搜" WebApp路由(基于AngularJS)如下:

    "豆搜" React Native版本导航如下:

    "豆搜" iOS版本导航代码如下:

    总结:React Native封装的导航控制更容易理解。

    (5)第三方生态链
    “我的是我的,你的也是我的。 ”——我不是“疯狂女友”,我是React Native!
    我们缺少“城市列表”组件,OK,使用JSX封装一个;觉得性能太低,OK,基于React Native方案封装一个原生组件。
    这个iOS图表库不错,拿来用呗! => 完美!
    这一切都是基于React Native提供的模块扩展方案。
    所以说:iOS第三方库 + 部分JavaScript库 = React Native 生态库

    2、性能 & 体验

    我们都很关注一款App性能。因此测试和体验App的性能很重要。以下测试,都是基于相同的case。
    测试平台:模拟器,iphone6,iOS8.4
    (1)内存
    首先,我们来看下Native应用占用的内存情况。一开始,原生应用启动后,占用内存是20~25M;针对相同的case,跑了2min,结果如下图:

    可以看出,峰值是87.9M,均值是72M;内存释放比较及时。

    我们再来看下Hybird App的情况。App已启动,占用内存35~55M;同样,跑了2min以上,结果如下图:

    可以看出,峰值在137.9M,因为整个应用在WebView中,内存释放不明显,存在缓存。

    最后,看下React Native的情况。App启动占用内存35~60M,同样跑2min以上,结果如下图:

    可以看出,峰值在142M,内存相对释放明显。

    总结:React Native和Web View在简单App上相差不大。二者主要:内存消耗主要是在网页数据上。

    (2)CPU
    我们可以看一下Native应用程序CPU的情况,最高值在41%。

    Hybird App的最高值在30%。

    React Native的最高值在34%。

    总结:CPU使用率大体相近,React Native的占用率低于Native。

    (3)动画
    React Native提供了Animated API实现动画。简单效果,基本OK。个人觉得React Native不适合做游戏,尤其布局能力。
    Native Animation提供UIView动画
    H5/Hybird:采用js动画能力
    总结:React Native Animated API / 封装Native动画库 可以满足基本需求

    (4)安装包体积
    Hybird App:
    34(App壳) + 5(HTML) + 125(Angular) + 29(An-route) + 6(min.js) + 4(min.css) = 203 KB。

    React Native:
    不含bundle: 843KB
    含bundle: 995KB

    Native
    83KB

    React Native框架包大小
    843(不含bundle) – 32(Hybird_app空壳,初识项目) = 811KB

    相比快速迭代和热更新,比Native多了811KB一点都不重要,我们将图片素材、静态资源线上更新缓存起来即可减少很多体积。
    总结:牺牲一点体积,换更大的灵活性!(世界上哪有那么美的事,除非丑,就会想得美,:) )。

    (5)Big ListView & Scroll 性能
    循环列表项500次: H5页面惨不忍睹
    React Native还可以接受
    Native 采用UITabView更高效,因为不渲染视图外部分。

    (6)真机体验
    机型:iphone4s,iOS7
    Native > React Native > Hybird
    如果非要给个数字的话,那我个人主观感受是:
    Native: 95%+ 流畅度
    React Native: 85~90% 流畅度
    H5/Hybird: 70% 流畅度

    总结:Native/React Native的体验相对而言更流畅。

    3、更新 & 维护

    (1)更新能力
    H5/Hybird: 随时更新,适合做营销页面,目前携程一些BU全部都是H5页面;但是重要的部分还是Native。
    React Native:React Native部分可以热更新,bug及时修复。
    Native:随版本更新,尤其iOS审核严格,需要测试过关,否则影响用户。

    (2)维护成本
    H5/Hybird: Web代码 + iOS/Android平台支持
    React Native:可以一个开发团队 + iOS/Android工程师;业务组件颗粒度小,不用把握全局即可修改业务代码。
    Native:iOS/Android开发周期长,两个开发团队。

    总结:React Native 统一了开发人员技术栈,代码维护相对容易。

    五、综合

    1、开发方式

    (1)代码结构: React Native更为合理,组件化程度高
    (2)UI布局:Web布局灵活度 > React Native > Native
    (3)UI截面图:React Native使用的是原生组件,
    (4)路由/Navigation:React Native & Native更胜一筹
    (5)第三方生态链:Native modules + js modules = React Native modules

    2、性能 & 体验

    (1)内存:Native最少;因为React Native含有框架,所以相对较高,但是后期平稳后会优于Native。
    (2)CPU:React Native居中。
    (3)动画:React Native动画需求基本满足。
    (4)安装包体积:React Native框架打包后,811KB。相比热更新,可以忽略和考虑资源规划。
    (5)Big ListView
    (6)真机体验:Native >= React Native > H5/Hybrid

    3、更新 & 维护

    (1)更新能力: H5/Hybird > React Native > Native
    (2)维护成本: H5/Hybird <= React Native < Native

    React Native定制难度相比Native有些大;但是具备跨平台能力和热更新能力。
    最后硬广一下我的书:


    展开全文
  • react native error

    万次阅读 2018-02-27 23:32:17
    react native Error react native Error: spawn cmd.exe ENOENT 没有启动react-native start 命令。 正确的启动react-native方式是: react-native start react-native run-android bulid failed ...

    react native Error

    react native Error: spawn cmd.exe ENOENT

    没有启动react-native start 命令。
    正确的启动react-native方式是:

    • react-native start
    • react-native run-android

    bulid failed

     Could not get unknown property 'MYAPP_RELEASE_STORE_FILE' for SigningConfig_Decorated{name=release, storeFile=null, storePassword=null, keyAlias=null, keyPassword=null, storeType=null, v1SigningEnabled=true, v2SigningEnabled=true} of type com.android.build.gradle.internal.dsl.SigningConfig

    原因:

    按照官网指示
    编辑~/.gradle/gradle.properties(没有这个文件你就创建一个),添加如下的代码(注意把其中的替换为相应密码)

    解决方法:

    gradle.properties文件应该使用RNProject/android/下面的gradle.properties
    也就是说在gradle.properties里面添加

    MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
    MYAPP_RELEASE_KEY_ALIAS=my-key-alias
    MYAPP_RELEASE_STORE_PASSWORD=*
    MYAPP_RELEASE_KEY_PASSWORD=*

    搞定

    Cannot find entry file index.android.js in any of the roots

    这里写图片描述
    出现如图错误,怎么弄都不行,index.android.js明明在根目录的,可是同事那边下的,在npm install后,拷贝过来又行了…

    然后想了想,我原来是用cnpm install安装的,可能是cnpm出了问题,果然重新用npm下了就好了

    unable to connect with remote debugger

    展开全文
  • Native】——关键字Native

    千次阅读 2018-11-08 14:42:15
    native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来...
  • native和static native区别

    千次阅读 2016-09-26 16:41:48
    本文基于Hello JNI ...native 与 static nativejava中 public native String helloJni(); public native static String helloJniStatic();JNI中JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_Jni
  • Android native memory leak detect (Android native泄露检测) 简介 Android应用中,经常会有业务需要使用到Native实现。比如加密,音视频播放等。也就是常见的二进制文件xxx.so 这部分代码,申请的内存不走...
  • Java的native方法

    万次阅读 多人点赞 2011-07-26 16:43:12
    第一篇:今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解。一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native ...
  • react-native-zyCountDown 用于react-native的计数组件,倒计时组件 封装的一个倒计时按钮,仅仅使用TouchableOpacity,View和Text. 安装 npm i react-native-zycountdown 或者 yarn add react-native-...
  • ReactNative之搭建环境

    万次阅读 2019-09-12 08:15:25
    今天就帮助大家想做RN开发的朋友们...中文:https://reactnative.cn/docs/getting-started.html 英文:https://facebook.github.io/react-native/ 首先要看朋友们是要开发Android还是iOS,如果是Android的话那么...
  • react-native 轮播图 ——react-native-swiper使用

    万次阅读 热门讨论 2017-05-23 23:02:31
    今天学习了轮播图的使用,上网查阅了一下,发现有react-native-swiper和React-Native-Viewpager 两种封装的比较好的第三方组件,对比了下文档,觉得react-native-swiper功能更加完善,而且文档说明比较全面,所以...
  • native关键字

    千次阅读 2017-09-25 17:23:51
    一直没有搞懂native的用法,今天看了好几位博主的文章,终于明白了。 参考:http://blog.csdn.net/xw13106209/article/details/6989415   概念: native是与C++联合开发的时候用的!使用native关键字说明这个方法是...
  • React Native

    千次阅读 2016-07-08 16:17:54
    Facebook 在 React.js Conf 2015 大会上推出了基于 JavaScript 的开源框架 React Native, React Native 官网:http://facebook.github.io/react-native/ GitHub 地址:...
  • react-native-camera是一个非常好用的RN调用摄像头的第三方库,github地址: https://github.com/react-native-community/react-native-camera 使用的时候有几处坑,在这里记录一下开发过程,首先效果图: 使用时先...
  • 在之前的 《Flutter vs Native vs React-Native: Examining performance》 对比中有一个颇有争议的点,其中有人提出正常情况下我们是不会在 React Native 进行这些重复和复杂的计算,虽然在这种情况下,使用 Flutter
  • React Native系列之Native Modules

    千次阅读 2015-10-07 16:56:53
    先来看下官网对于Native Modules的描述: Sometimes an app needs access to a platform API that React Native doesn’t have a corresponding module for yet. Maybe you want to reuse some existing Java code ...
  • ReactNative读取Native本地文件

    万次阅读 2016-10-17 20:23:43
    1, LatticeMockModule.java 声明一个Native模块给RN提供调用 /**此类为RN提供读取配置文件的功能*/ public class LatticeMockModule extends ReactContextBaseJavaModule { .... private final static String ...
  • ReactNative常用命令

    千次阅读 2020-10-13 14:22:07
    ReactNative 常用命令 创建项目 react-native init 项目名 查看是否有设备连接 adb devices 运行Android工程 react-native run-android 运行Ios工程 react-native run-ios 用指定设备运行Ios工程 react-...
  • ReactNative初级到项目实战

    千人学习 2017-12-19 21:25:34
    对课程有什么问题或者有什么好的建议都可以联系Hank老师QQ:471926977 ...新颖、实用、详尽的ReactNative初级课程,本 教程涵盖ReactNative官方的新组件和实践,甚 至包括尚未正式发布的新特性 时”!
  • [ReactNative入门到精通]React Native概述

    万次阅读 热门讨论 2015-10-11 01:15:10
    2015年9月15日,Facebook发布了 React Native for Android,把 Web 和原生平台的 JavaScript 开发技术扩展到了 Google 的流行移动平台。什么是React NativeReact Native 让开发者使用 JavaScript 和 React 编写应用...
  • react-native-video 是一个播放视频的开源组件, 它的用法很简单。 1.安装 依次执行下面两个命令, npm i -S react-native-video react-native link (这一步是连接本地视频库) (1) ios: 如果您想允许其他应用...
  • Kotlin Native实战开发

    万次阅读 2018-07-31 21:25:30
    Kotlin Native是一种将Kotlin源码编译成不需要任何VM支持的目标平台二进制数据的技术,编译后的二进制数据可以直接运行在目标平台上,它主要包含一个基于LLVM的后端编译器的和一个Kotlin本地运行时库。设计Kotlin ...
  • iOS React Native 混合开发集成React Native

    千次阅读 2017-07-24 17:47:51
     有时候我们并不是需要全部使用React Native,我们想和原生混合开发,那我们应该怎么办呢。 先看一下我集成完之后的项目目录: 首先安装React Native node组件  1、新建一个文件夹如目录中的RN,这个...
  • 简述什么是 Cloud Native

    千次阅读 2019-03-04 22:29:04
    Cloud Native(云原生)是以云架构为优先的应用开发模式。目前,越来越多的企业已经在大规模开始拥抱云,在云环境开发应用、部署应用、发布应用。未来,越来越多的开发者也将采用 Cloud Native 来开发应用。本书是...

空空如也

1 2 3 4 5 ... 20
收藏数 271,281
精华内容 108,512
关键字:

native