React Native有什么UIxposed框架使用教程可以使用吗

自由、创新、研究、探索
Linux/Windows Mono/DotNet [ Open Source .NET Development/ 使用开源工具进行DotNet软件开发]锐意进取,志存高远.成就梦想,只争朝夕.从你开始,创新世界.【That I exist is a perpetual supprise which is life. Focus on eCommerce】
&React Native是一套使用 React 构建 Native app 的编程框架
what is React Native?
跟据官方的描述, React Native是一套使用 React 构建 Native app 的编程框架. 推出不久便引发了广泛关注, 这也得益于 JavaScript 开放而活跃的技术社区和 React Native 完备的技术体系支持. 本文试图概括的介绍 React Native.
React Native 主要是一套 Runtime, 包括一套 React.js 库使得开发可以用 React 的方式开发, 以及一套 Native 的Ployfill 弥补webkit 渲染&&交互能力的不足.
javascript runtime运行在 JavaScriptCore 上, JavaScriptCore 是WebKit的 JavaScript 引擎, 也就是 Safari 中的 JavaScript 引擎, Apple 把他叫做 Nitro. JSC 自从2008年诞生, 至今做了很多优化, 成熟的执行引擎保证了运行效率. RN 本身没有和 js 引擎绑定, 选择 JavaScriptCore 的原因是 iOS 对 JSC 的天然支持.
how React Native works?
React Native 通过执行javascript, 计算出布局 样式 事件处理的信息, 保存到一个类似于DOM的数据结构(ReactElement tree)中. 通过pure native组件渲染出UI. 事件处理上也是首先native先处理, 再根据javascript的事件监听调用响应的callback. 是将javascript的逻辑能力和native的性能的折中整合.
在组件开发和复用方面, ReactNative 采用了 RequireJS 对组件的组织方式. RequireJS 在 node 中广泛使用, 同 npm 结合让组件的重用变得简单. 一个文件就是一个组件, 组件可以发布到 npm 仓库, 通过配置描述组件名称和版本, 其他开发可以直接引用现有的组件. 同 cocoapods 和 maven 类似, 解决了 js 代码依赖管理和协作的问题.
在组件开发上面, UI 开发方式上面沿用了 React 的优秀设计, React.js 在 javascript 界掀起了一场热潮, 将 面向DOM 的开发方式变为以面向组件的开发. 这倒是和 native 的开发模式很像, 先设计静态组件样式, 再处理交互流程, 抽离可变状态. 但是 React 加上 javascript 的编程能力是 Java 和 OC 不能比的... React 利用 Babel 支持了 ES6的语法, 并为了简化 DOM 的编写设计了 JSX, 这些大大简化了开发量, 并使得开发变得有趣. React 也采用了依赖反转的设计, DOM 重绘, 组件的生命周期, 都是由React.js控制, 开发只需要关心UI 和交互设计, 可以参考 iOS 中的各种生命周期的 delegate 理解.
Native和javascript的通信是通过native调用javascript实现的, 调用只能是单向的, 总是从native到js. 这套机制目前已经比较成熟, 但RN通过实现对象传递和batch处理js回调的方式解决了双向通信和性能的问题, 对于开发者就像能够做到双向的调用一样. 在 Native 部分, RN 提供了 javascirpt 和 Native 通信时对象传递的方案, 并通过单向调用返回注册callback的方式, 让native在恰当的时机回调js方法, 并且通过让Native 组件运行在独立线程的方式和batch调用callback的方式优化整体的性能.
RN 官方提供了很多 Native 的组件, 并且由于其开放性, 网上有很多 react-parts 这些开源的组件库, 开发者可以用他们做出精细的交互设计.
Disadvantage
loadtime问题, 由于RN是以javascript为主体的设计, 页面渲染需要先执行一次javascript render调用. 目前经过一些优化后(framework抽离复用, js资源cache)在iPhone5上面测试简单的页面渲染, js执行的时间要200ms左右, 这个时间主要是在第一次js执行的开销. 这个时间对于用户是可以感知的, 而且会随着js的复杂增长.
内存开销. 由于依赖了js引擎, 在内存占用上会明显高于pure native, 这对于android的低端机而言问题尤其严重.
功耗, 由于额外的js的执行频繁的通信需要的序列化操作都会造成功耗的上升, 虽然没有亲测过具体的差距, 但功耗也是值得关注的问题之一.
虽然存在这些问题, 但动态能力对于native开发而言的诱惑太大, native开发还是需要根据要解决的问题选择合适的技术. 对于js开发而言, 使用自己熟悉的环境能够大幅提升在客户端的体验, 是非常棒的技术.
https://facebook.github.io/react-native/http://trac.webkit.org/wiki/JavaScriptCore/2012/06/nitro-javascriptcore-and-jit.html/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome/item?id=8964935/blog/react-native-bridge/
原创文章, 转载请注明来源&/hucn/p/5077713.html &http://nickolashu.github.io//react-native-at-first-sight/
更多文章关注我的个人博客
http://nickolashu.github.io/
阅读(...) 评论()
随笔 - 15982
评论 - 13429116人阅读
【Android 新技术预研】(49)
【React Native Android】(8)
【Android 基础】(147)
Android React Native 已经将几个常用的原生组件进行了封装,比如 ScrollView 和 TextInput,但是并不是所有系统的原始组件都被封装了,因此有的时候我们不得不自己动手封装一下,从而能够使用那些React Native没有为我们封装的原生组件,比如WebView,官方并没有提供Android端的实现,那么我们现在就动手封装一下WebView。
之前写过一篇文章,而使用原生UI组件的方法和使用原生模块的方法十分类似。
首先,我需要继承SimpleViewManager这个泛型类,和原生模块类似,需要重写getName()方法,将UI组件名称暴露给javascript层,接着需要重写createViewInstance方法,在里面返回我们需要使用的原生UI组件的实例,这里就是WebView。然后就是暴露一些必要属性给javascript层,为了简单起见,我们这里只暴露两个属性,一个是url,一个是html,一旦javascript层设置了url,就会加载一个网页,而一旦设置了html,则会去加载这段html,而属性的暴露是使用注解,将注解设置在对应的set方法上,之后再set方法中处理UI的更新,比如一旦设置了url,在setUrl里面就要加载网页。最终我们的ViewManager就是这样子的
<pre class="prettyprint prettyprinted" data-original-code="public class ReactWebViewManager extends SimpleViewManager {
public static final String REACT_CLASS = &RCTWebView&;
public String getName() {
return REACT_CLASS;
protected WebView createViewInstance(ThemedReactContext reactContext) {
WebView webView= new WebView(reactContext);
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return webV
@ReactProp(name = &url&)
public void setUrl(WebView view,@Nullable String url) {
Log.e(&TAG&, &setUrl&);
view.loadUrl(url);
@ReactProp(name = &html&)
public void setHtml(WebView view,@Nullable String html) {
Log.e(&TAG&, &setHtml&);
view.loadData(html, &text/ charset=utf-8&, &UTF-8&);
}" data-snippet-id="ext.329b12fecf9cb" data-snippet-saved="false" data-csrftoken="YovcNaBu-lenjyfTe3r17RMPlzP81oURyVgs" data-codota-status="done">public class ReactWebViewManager extends SimpleViewManager&WebView& {
public static final String REACT_CLASS = "RCTWebView";
public String getName() {
return REACT_CLASS;
protected WebView createViewInstance(ThemedReactContext reactContext) {
WebView webView= new WebView(reactContext);
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
return webV
@ReactProp(name = "url")
public void setUrl(WebView view,@Nullable String url) {
Log.e("TAG", "setUrl");
view.loadUrl(url);
@ReactProp(name = "html")
public void setHtml(WebView view,@Nullable String html) {
Log.e("TAG", "setHtml");
view.loadData(html, "text/ charset=utf-8", "UTF-8");
和原生模块一样,原生UI组件也需要进行注册,实现ReactPackage接口,进行WebView的注册。
<pre class="prettyprint prettyprinted" data-original-code="public class AppReactPackage implements ReactPackage {
public List createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();;
public List<Class> createJSModules() {
return Collections.emptyList();
public List createViewManagers(ReactApplicationContext reactContext) {
return Arrays.asList(
new ReactWebViewManager());
" data-snippet-id="ext.b3c26f8f90dc93c90cac" data-snippet-saved="false" data-csrftoken="pAWMZxSf-LITk3G4glq3DgVmMEiqiHgeAN6k" data-codota-status="done">public class AppReactPackage implements ReactPackage {
public List&NativeModule& createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();;
public List&Class&? extends JavaScriptModule&& createJSModules() {
return Collections.emptyList();
public List&ViewManager& createViewManagers(ReactApplicationContext reactContext) {
return Arrays.&ViewManager&asList(
new ReactWebViewManager());
将这个ReactPackage添加到ReactInstanceManager实例中去
.addPackage(new AppReactPackage())
然后在javascript层新建一个WebView.js文件。输入下面的内容
'use strict';
var { requireNativeComponent,PropTypes
} = require('react-native');
var iface = {
name: 'WebView',
propTypes: {
url: PropTypes.string,
html: PropTypes.string,
module.exports = requireNativeComponent('RCTWebView', iface);
可以看到,我们只是在里面指定了属性的类型。
到目前为止,你已经可以使用这个WebView组件了。
WebView=require('./WebView');
render: function() {
&View style={styles.container}&
url="" style={{width:200,height:400}}
这里只是简单加载了一下百度首页,有一点需要特别注意,就是组件的宽度高度一定要设置,否则你会看不到这个组件。最终效果如下。
这还只是最基础的将原始UI组件显示出来,而更为常见的却是事件,比如我们需要在javascript层处理这个WebView的滚动事件,这时候又要怎么做呢。
这时候我们就需要继承WebView,重写对应的事件,然后将事件传递给javascript层了
我们重写了滚动时回调的onScrollChanged方法,构造了一个WritableMap 对象,将ScrollX和ScrollY传入,然后调用reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(getId(), “topChange”, event);将事件发生到javascript层,注意topChange对应着javascript层的onChange方法,这个映射关系在UIManagerModuleConstants类中。
然后我们需要修改ReactWebViewManager 中的createViewInstance方法,在里面返回我们实现的子类,就像这样子
protected WebView createViewInstance(ThemedReactContext reactContext) {
WebView webView= new RTCWebView(reactContext);
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
return webV
而javascript层也需要进行一定程度的改造,最终的代码如下
<pre class="prettyprint prettyprinted" data-original-code="'use strict';
var React = require('react-native');
requireNativeComponent,
class WebView ponent {
constructor() {
this._onChange = this._onChange.bind(this);
_onChange(event: Event) {
if (!this.props.onScrollChange) {
this.props.onScrollChange({ScrollX:event.nativeEvent.ScrollX,ScrollY:event.nativeEvent.ScrollY});
render() {
WebView.propTypes = {
url: PropTypes.string,
html: PropTypes.string,
onScrollChange: PropTypes.func,
var RCTWebView = requireNativeComponent('RCTWebView', WebView,{
nativeOnly: {onChange: true}
module.exports = WebView" data-snippet-id="ext.dd3fbda2fc1aea163b84" data-snippet-saved="false" data-csrftoken="M7VXVSiz-JsluEvZfqm_oyONV-uHimEkfOvM" data-codota-status="done">'use strict';
var React = require('react-native');
requireNativeComponent,
class WebView extends React.Component {
constructor() {
this._onChange = this._onChange.bind(this);
_onChange(event: Event) {
if (!this.props.onScrollChange) {
this.props.onScrollChange({ScrollX:event.nativeEvent.ScrollX,ScrollY:event.nativeEvent.ScrollY});
render() {
return &RCTWebView {...this.props} onChange={this._onChange} /&;
WebView.propTypes = {
url: PropTypes.string,
html: PropTypes.string,
onScrollChange: PropTypes.func,
var RCTWebView = requireNativeComponent('RCTWebView', WebView,{
nativeOnly: {onChange: true}
module.exports = WebView
不要问我为什么是这样子的,因为官方文档上就是在这么写的,你只需要复制代码,进行修改即可,详见文档
这里需要注意的就是function.bind(this)的语法了,有兴趣的自己去网上搜,这块我也讲不清楚,毕竟没怎么学过javascript和React,怕误人子弟。在onChange函数中,我们进行判断,如果属性onScrollChange没有设置,就直接return,否则就调用设置的onScrollChange属性值(该值是一个函数类型),将Java层传入的两个参数传到该函数中去,{ScrollX:event.nativeEvent.ScrollX,ScrollY:event.nativeEvent.ScrollY}
然后我们来进行调用
WebView=require('./WebView');
render: function() {
&View style={styles.container}&
&WebView onScrollChange={this.onWebViewScroll} url="" style={{width:200,height:400}}(event){
console.log(event);
这时候等待WebView加载处理,你再上下滑动,就会看到控制台的输出,如下
以上就是使用原生UI组件的全部流程,可以看出React Native官方已经为我们做了很好的封装,我们只需要编写少量的代码,就可以使用原生UI组件了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:883446次
积分:9996
积分:9996
排名:第1445名
原创:164篇
评论:689条
阅读:87283
阅读:19960
阅读:97876
阅读:24481
阅读:35315从Samurai-Native框架开发谈React Native
发表于 16:16|
作者郭虹宇
摘要:F8大会的主题折射出一个非常重要的观点,未来Web前端开发与Native移动应用开发工程师的工作职责很可能会相互重叠,平台之间的边界不会太明显,还会产生更专注于跨平台App UI及交互构建的“全终端开发工程师”。
近一年移动开发领域最火的话题就是“Web与Native正在融合”,React Native的出现是推动融合的一个关键点。正如F8大会的主题“Bring modern web tech to mobile”,巨头们已经着手从上自下展开技术融合,Web App开发者们与Native App开发者们长年相互鄙视斗争的过程将要告一段落。Web App开发者们实在是受够了HTML5应用的诸多基础体验问题,如:加载时间长,用户体验差,动画效果弱等。Native App开发者则是对于变化的需求以及App Store审核时间无法平衡。因此,从React Native发布起,如一阵夏日凉风唤醒了沉睡的开发者,使得这类技术近期备受关注。React Native实现解决的是前端开发者可以使用相同的技术体系来解决跨平台应用开发的问题,并以创建HTML及CSS子集通过WebCore技术与原生结合构建出与体验上几乎无差别的App。一来HTML5原有痛点被消除,二来前端技术栈被保留,难道前端开发工程师的春天真的来了?Web与Native交叠:未来的全终端开发工程师F8大会的主题折射出一个非常重要的观点,未来可能Web前端开发工程师与Native移动应用开发工程师的工作职责会相互重叠,所持技能及开发环境会趋向于统一,平台之间的边界不会太明显,未来的几年可能会产生一种新的职位叫做“全终端开发工程师”,属于“全栈”系列的前半部分,他们会更专注于跨平台App的UI及交互构建,使多平台体验一致,从iOS App、Android App到HTML5 App的UI开发。就此方向,React Native才给出了一个大一统的口号:“Learn once,write everywhere”。为什么?想想就知道了。React Native其实并不算是新技术,以往BeeFramework(XML+CSS)、NativeScript(JS+CSS)等都有类似的实现,但它们只专注于Native平台并使用了一些非标准或不为前端开发者而熟知的技术。React Native思维最大的不同在于,基于ReactJS的知识体系,只要学过一次就可以写遍全平台,那么我们可以认为iOS只是一个开始(Facebook野心是巨大的)。React Native因何而来?React Native能够被设计并实现,我个人以为是得益于作者对于浏览器技术和Virtual DOM技术的深度技术思维及扩展,因为在基于此项技术的基本模型及模式建立好的情况下,架接于任何一个平台来实现将不再是难事。我们能够看到React Native中有类似于WebKit的影子,比如Shadow View和CSS Node。在内存中,这两种基本元素构建出能够表达UI结构的一种通用模型,那么在任何一个平台上只要遵循这个规则,都将可以描述出一个UI是“长什么样子”,有些类似于浏览器中的DOM Tree + Style Tree。基于此,React Native通过ReactJS又实现了一套平台无关的触控处理及数据绑定,这样将原来平台相关的代码抽离到了平台无关的JavaScript语言来实现,大大降低了React Native开发者对平台特性及语言的依赖。回顾浏览器的发展历史,从20年前Netscape发布了Navigator到如今的Chrome及Safari,浏览器内核的本质没有什么变化,输入进入的是UIML(如HTML),其核心WebCore帮你加载、解析、构建、计算出页面中每个元素结点上下级关系、位置、及样式。不幸的是,W3C对于HTML5标准的确立与推进也过于缓慢,而且标准与需求明显严重脱节,颇有些鸡肋之感。W3C几乎错失了在移动端的布局机会,甚至我们不清楚这帮大佬是不是真的有考虑Web技术在移动端发展的未来,让人不禁想问,为什么React Native这类技术不是由Google和Apple两大WebKit拥护者及手机操作系统开发商发起并实现的?未来又将如何?所以,此时必然会出现其他一些不甘寂寞的巨头浮出水面,给出答案。那就是,尝试重造足够好的轻量级WebCore,用于满足同时具有原生性能及体验,并也具有Web开发效率的全新技术。关于这一点,我觉得React Native偏离得有些远,Facebook最初更多的只是为了解决自己内部的需求,现在是想借ReactJS吸引更多的开发者来重造一个“通天塔”。自然,时间长了会出现两种结果,一种是Web与Native融合,另一种则是Web与Native分裂。而分裂的结果是,Facebook强行撕裂一些W3C身上对自己有利的肉,翻炒之后做成React这道菜。对于企业来说,全面换用React Native的时机还不够成熟,至少在Android版本推出后再看。笔者本人也看过React Native iOS的实现代码还有待改善。取精华去糟粕,Samurai-Native框架与React Native有哪些不同?最后,再说说我所开发的Native App框架Samurai-Native。与React-Native相反,Samurai-Native的理念是使Native开发者可以使用标准Web技术(HTML+CSS)解决跨平台UI开发的问题,已在Github上。Samurai-Native架构图Samurai-Native与React Native相比有着诸多不同,后者在Native部分拥有着很多已经让人无力吐槽的实现:&Text&不是UILabel或类似控件,而是drawRect,这样的问题是accessibility很差,无法选择复制粘帖,也无法实现富文本效果。&Text&不能嵌套,不能够使用Web开发者思维来构建文本段。&List&不是UITableView或UICollectionView,而是通过UIScrollView实现的简单列表,无法满足后续复杂需求。不能使用GestureRecognizer,而是由JS简单判断点击区域来实现手势识别。不能使用ResponderChain,事件机制只能使用ReactJS提供的方式。JSX:让人无法想像的历史倒退,W3C通过20年将 “布局、样式、数据” 三者分享,Facebook只花了几个月就能合并到一起了。CSS-layout,只支持Flex-Box,不支持Fluid(流式)布局。CSS不支持继承和叠加,不支持多Class。HTML标准标签均无法使用。Native API需要手动导出,当iOS系统升级时,可能会带来兼容性问题。控件必须继承自RCTView,并需要定义RCTViewManager,难以将现有控件为React-Native所用。全局hook了触屏事件,由root view转发给touch handler,再用60fps的timer刷新给ReactJS来处理,无法想像的实现方式……无法使用onclick,必须包裹一层&TouchableHighlight&,使布局结构变得极为复杂。需要使用Chrome调试App,而无法使用原生IDE,调试过程变得极为复杂。Samurai-Native的UI HTML示例代码因此,在开发Samurai-Native的过程中,笔者专门针对这些问题进行了改善,取React Native精华,让它们成为Samurai-Native中的优势:支持标准HTML;支持标准CSS;支持UITableView;支持UICollectionView;使用原生GestureRecognizer;使用原生ResponderChain;UI layout、style、data完全分离;支持Fluid布局;支持样式继承和叠加,支持多Class;支持部分标准HTML标签(有做取舍);支持原生控件直接导入,只需要通过&YourView/& 标签命名即可;支持onclick、onpan、onswipe多种手势;使用Xcode调试。为什么选择HTML+CSS的组合,而不再使用类似于React-Native或BeeFramework的XML?主要原因是不想再造轮子。HTML经过20年的时间检验,已经足够成熟,是最好的复杂UI布局的描述语言。Samurai-Native工作流程图那么总结起来,Samurai-Native的终极目标是想做成一个标准的Web浏览器内核,来为开发者们提供一款W3C标准WebCore的跨平台UI解决方案,既能渲染Web页面,又能生成原生View树。通过私有浏览器内核技术(Objective-C编写)将HTML+CSS解析渲染成为Native View树,从而既有Web开发体验,又有不错的用户体验。(责编/唐小引)作者简介:郭虹宇(),有着近十年的移动App开发及架构经验。曾在腾讯无线部门做研发Leader,目前经营开源工作室Geek-Zoo Studio。CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面,如果您有想分享的技术、观点,可通过电子邮件(tangxy#csdn.net,请把#改成@)投稿。第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章}

我要回帖

更多关于 xposed框架使用教程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信