个人博客:haichenyi.com。感谢关注
新公司,新的开始,新的技术
新公司的项目,用到的RN编程,之前完全没有碰到过,遇到新技术,之前完全没有碰到过怎么办?google、百度咯。通过不屑的努力,找到了恋猫月亮 的三篇关于RN的文章。我感觉还是很不错的。
从Android到React Native开发(二、通信与模块实现)
从Android到React Native开发(三、自定义原生控件支持)
可以先浏览上面的第一篇入门,再过来看我这篇文章,我这篇文章就是讲怎么运行一个RN,我只是针对我的项目,把RN的部分提取了出来,上面大佬讲的比较全面。
React Native环境配置
开发工具:android studio。我不知道为什么要换开发工具。AS不好吗?环境还是跟你之前开发的一样配置,不用变
python安装:python官网,下载安装。记得配置环境变量。不用非要按照他那个上面说的去安装。安装完成之后cmd里面敲python然后回车,看到如下界面:
node.js安装:node也是一样,百度安装,配置完环境变量。cmd里面敲 npm -v然后回车,看到如下界面
最后,跑如下命令:
1 | //安装完node后建议设置npm镜像以加速后面的过程(或使用科学上网工具)。 |
至此,RN的配置就完成了。记得配置NDK环境,然后就是上你们公司的svn,或者git去down项目下来,应该还会有一个错误,那就是找不到react.gradle的路径,找到你添加依赖的那个gradle,在最上面添加如下代码:
1 | apply from: "../../node_modules/react-native/react.gradle" |
这个配置应该是添加greenDao那个是一样的,这样就能找到了react.gradle
项目结构如下:
我用箭头标记了,你down下来的项目,应该是没有node_modules文件夹的,这个文件夹是怎么产生的呢?你在cmd进入你down的项目,就是图片上面的文件目录,跑如下命令即可
1 | npm install |
当命令运行完,就可以跑项目了。
React Native项目搭建
同鞋,你有freeStyle吗?有没有用过WebView?WebView就是在你的xml里面新增了一个WebView控件,RN也一样,他的这个控件就是ReactRootView。所以,这个控件哪里来?当然是添加依赖了
1 | //版本号你自己找 |
最终的作用代码就是:
1 | mReactRootView.startReactApplication(mReactInstanceManager, "XXX", null); |
这个ReacRootView对象,你可以new出来,也可以写在xml里面findViewById。只要你能获取到这个对象就可以了,然后就是这个方法:
1 | startReactApplication(ReactInstanceManager reactInstanceManager, String moduleName, @Nullable Bundle initialProperties) |
三个参数
- ReactInstanceManager reactInstanceManager
- String moduleName
- @Nullable Bundle initialProperties
第一个参数:ReactInstanceManager
就像配置WebView的参数,那些什么配置client允许js弹窗啊,新的页面直接覆盖原来的页面,并不是新建一个页面之类的参数,对应的这里,就是配置ReactInstanceManager
1 | ReactInstanceManagerBuilder builder = ReactInstanceManager.builder(); |
前面的builder的初始化是必须要写的,setApplication,如果你没有自己写application,那就直接getApplication,如果,你有自己实现application那就传你的application对象。
setBundleAssetName和setJSMainModulePath都是写死的,后面的名字也是写死的。
然后就是添加package,在package里面添加module。这里就是JS和Android相互调用的地方。package里面要实现ReactPackage,在createNativeModules里面去添加moudle
第二个参数:String moduleName
这个moudleName是怎么来的?就是我们前面设置的MoudlePath那个JS里面的。这里的路径应该是index.android.js,是一个js文件,打开之后,最下面有如下代码:
1 | AppRegistry.registerComponent('zzz', () => XXX); |
这里的zzz就是我们这里需要传的名字
第三个参数:Bundle initialProperties
这里应该是传一个bundle,传输的数据,传个null就可以了
React Native流程
前面的整个配置都配置完成之后,Android这边只用新建方法,给RN调用就可以了。新建的方法要用@ReactMethod标记。辣么,这个方法新建在哪呢?————Module,就是对应我们前面package里面添加的module。都说RN每个模块是独立的,怎么独立呢?就是这样独立的。每个模块功能对应一个module,每个都有该功能对应的方法。我就拿我这里的UserModule来举个例子
1 | public class UserModule extends IModule implements NoticeListener{ |
这里我就粘贴出来了部分代码,module要继承IModule,这个是一个抽象类,他继承ReactContextBaseJavaModule,最主要就是继承它,继承之后,我像说的就是这两个方法,getName()和注解的方法doLogin()。
我们可以看到,这个getName最终返回的是一个User_Module,这个字符串是怎么确定的呢?这个登录的方法名称是怎么确定的呢?
这些东西都是在js里面定义好的,这里是一个登录方法,我们打开登录的js。
PS: 这里应该是通过js去确定我们这边的方法名,并不是通过这里的名称去确定js的。
我就不把JS代码,贴出来了,只贴出伪代码,打开js之后,搜索NativeModules。你应该会搜到类似的代码:
1 | const { User_Module, Shop_Module } = NativeModules; |
这里有两个Module,没错,就是两个。我们这里现在只关注User_Module,然后,我们搜索 User_Module,你会看到如下代码:
1 | _onLogIn = () => { |
其他的一切,我们都不用管,我们在意的是
1 | User_Module.doLogin(JSON.stringify(params), (...values) => { |
上面这个是我的项目里面的js,你们搜到的肯定跟我的不一样,我这里要说的是,怎么确定name的返回值,和注解方法。我们看到了,name就是这里的User_Module,方法就是这里的doLogin,android里面写用@ReactMethod标记,然后就是参数了,这里两个参数,一个是String,json格式的。用ArrayMap存储好key—value之后,转成字符串即可。第二个参数就是callback。android与JS通信,发送数据,就是一个方法
1 | callback.invoke("data") |
他需要什么,你就发送什么。上面是RN主动调用Android方法,辣么,Android怎么主动调用RN方法呢?其实也很简单
1 | //发送给RN |
就是获取ReactContext对象,通过调用getJSModule方法,参数传DeviceEventManagerModule.RCTDeviceEventEmitter.class这个类就可以了,然后通过调用emit方法,第一个参数,就是RN规定的方法名称,第二个参数就是需要传给RN的数据。为什么这样写呢?我们再来看看RN那边是怎么写的
1 | DeviceEventEmitter.addListener("push_data_rn",(data)=>{ |
他就是通过这DeviceEventEmitter类添加addListener方法,传两个参数,第一个参数就是我们规定的名称,第二个参数就是一个回调,有一个参数,就是用来接收我们的数据,最后做的处理就是简单的弹窗,当然,这是我自己测试用的,最后RN要怎么坐,就是我要担心的问题了。