Android原生嵌入React Native 过程中遇见的各种坑
2016-09-01 21:57
477 查看
首先说说情况吧,公司需要原生嵌入ReactNative,迫于需要,要搞起来。看着iOS就搞了20分钟,感觉Android就算麻烦也不能太麻烦的,结果还是自己太年轻了。下面就是我遇到的各种问题,希望对看到的朋友能有帮助
(我用的是ReactNative版本为0.32.0)
1.首先集成的项目目录
我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的
Android项目目录是跟node_modules是在一个目录下的。
我试过把node_modules集成在Android项目下面的情况,不过没有弄成,所以我换乘来
这种了(有时间可以再试试)
2.第二步就是跟官网和很多教程一样的配置环境了
2.1 在我们Android项目的build.gradle中添加React Native依赖,然后同步,具体代码如下:
在此说一下,我也是忘记在哪个大神博客下看的了,如果版本写的是“+”的话,下载的react native版本就是0.20.0的版本,会报一个错,就是版本不符合的错误,“Module 0 is not a registered callable moudle”,这个Google了一下,说是reactnative版本跟服务器的版本不符合,改正了就按着我的步骤三的第一种方法做就可以了,注释掉第三个重写的方法。
2.2紧接着我们需要在项目AndroidManifest.xml中加入网络访问权限
还有一个activity就是设置菜单,发现好多里面都没有,我就先放在这里了
2.3 在
我是在两个 jcenter() 后面都添加了这个方法
3.在Activity中添加代码
这里有两种方法都是可以加载的。
第一种:
?
由于我使用的是第0.32.0版本的react native,所以运行的时候,最后一个重写的方法会报错的,于是就注释掉了,但是不要担心,getPackages方法写到MainApplication里就可以了
如果不写的话,会有一个Application强转错误的
第二种,
我开始使用的是第一种,但是后来发现使用第一种的话,最后运行的话只能打包固定的代码,并不能实现热更新(毕竟新手,没有发现这么搞),所以果断改第二种了,修改js文件直接就能reload实现了,非常的嗨
4.添加react native包
这就比较简单了,看了好多的文档都是这么写的,也可以直接从init 的项目里拷过来就好,或者按着官方的来就好
$ npm init
跟着步骤回车就好了,然后好像输入个yes
然后就发现有了一个package.json文件
然后就是 npm install ,导入react包了
然后就是
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
做一下flow配置 虽然现在不知道是为了什么,但是每个人都这么做
5.添加Js代码
6.运行Demo
开开reactnative的服务器,npm start
在studio中运行demo,会发现,出现一行“哈哈哈哈”
注:可能会出现java.lang.RuntimeException: Could not get BatchedBridge, make sure your bundle is packaged correctly这个错误,Google就有解决方法,就是在命令行里运行
注意assets的目录,我是在里面直接新建了index.android.bundle和index.android.map两个空文件,然后运行的,会自动往里面写入代码,然后运行就可以了
本人第一次写这些自己的经验,有不足之处,希望大家海涵,因为是后来写的,有些东西可能还是忘记了,如果有碰到什么问题的话,可以直接回复,谢谢
我在自己做的时候,也参考了好多大神的文章,都有很大帮助,他们的文章都在百度的前几个,所以也好找,
谢谢观看
(我用的是ReactNative版本为0.32.0)
1.首先集成的项目目录
我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的
Android项目目录是跟node_modules是在一个目录下的。
我试过把node_modules集成在Android项目下面的情况,不过没有弄成,所以我换乘来
这种了(有时间可以再试试)
2.第二步就是跟官网和很多教程一样的配置环境了
2.1 在我们Android项目的build.gradle中添加React Native依赖,然后同步,具体代码如下:
compile 'com.facebook.react:react-native:0.32.0'
在此说一下,我也是忘记在哪个大神博客下看的了,如果版本写的是“+”的话,下载的react native版本就是0.20.0的版本,会报一个错,就是版本不符合的错误,“Module 0 is not a registered callable moudle”,这个Google了一下,说是reactnative版本跟服务器的版本不符合,改正了就按着我的步骤三的第一种方法做就可以了,注释掉第三个重写的方法。
2.2紧接着我们需要在项目AndroidManifest.xml中加入网络访问权限
<uses-permission android:name="android.permission.INTERNET" />
还有一个activity就是设置菜单,发现好多里面都没有,我就先放在这里了
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
2.3 在
android/build.gradle文件中(注意跟上面的路径不同)加入本地React Native的maven目录(现在React Native的所有组件,无论JS还是Android的预编译包,都是通过npm分发的了):
我是在两个 jcenter() 后面都添加了这个方法
maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url "$rootDir/../node_modules/react-native/android" }
3.在Activity中添加代码
这里有两种方法都是可以加载的。
第一种:
public class MainActivity extends ReactActivity { @Override protected String getMainComponentName() { return "<span style="font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Hiragino Sans GB", 微软雅黑, "WenQuanYi Micro Hei", STHeiti, SimSun, sans-serif; line-height: 2em;">MyAwesomeApp</span><span style="line-height: 2em; font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", "Hiragino Sans GB", 微软雅黑, "WenQuanYi Micro Hei", STHeiti, SimSun, sans-serif;">";</span> } @Override protected boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } // @Override // protected List<ReactPackage> getPackages() { // return Arrays.<ReactPackage>asList( // new MainReactPackage() // ); } }
?
由于我使用的是第0.32.0版本的react native,所以运行的时候,最后一个重写的方法会报错的,于是就注释掉了,但是不要担心,getPackages方法写到MainApplication里就可以了
public class MainApplication extends Application implements ReactApplication { private Application context; @Override public ReactNativeHost getReactNativeHost() { context = this; ReactNativeHost host = null; if (host==null){ host = new ReactNativeHost(context) { @Override protected boolean getUseDeveloperSupport() { return false; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new IntentReactPackage() ); } }; } return host; } }
如果不写的话,会有一个Application强转错误的
第二种,
public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler { private ReactRootView mReactRootView; private ReactInstanceManager mReactInstanceManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //创建一个ReactRootView,把它设置成Activity的主视图 mReactRootView = new ReactRootView(this); mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setBundleAssetName("index.android.bundle") .setJSMainModuleName("index.android") .addPackage(new MainReactPackage()) .setUseDeveloperSupport(BuildConfig.DEBUG) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); mReactRootView.startReactApplication(mReactInstanceManager, "MyAwesomeApp", null); setContentView(mReactRootView); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } //传递一些Activity的生命周期事件到ReactInstanceManager,这是的JavaScript代码可以控制当前用户按下返回按钮的时候作何处理(譬如控制导航切换等等)。如果JavaScript端不处理相应的事件,你的invokeDefaultOnBackPressed方法会被调用。默认情况,这会直接结束你的Activity。 @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostPause(); } } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostResume(this,this); } } @Override public void onBackPressed() { // mReactInstanceManager.showDevOptionsDialog(); Toast.makeText(this, "dianjialefanhuijian", Toast.LENGTH_SHORT).show(); if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } //我们需要改动一下开发者菜单。默认情况下,任何开发者菜单都可以通过摇晃或者设备类触发,不过这对模拟器不是很有用。所以我们让它在按下Menu键的时候可以显示 @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } }
我开始使用的是第一种,但是后来发现使用第一种的话,最后运行的话只能打包固定的代码,并不能实现热更新(毕竟新手,没有发现这么搞),所以果断改第二种了,修改js文件直接就能reload实现了,非常的嗨
4.添加react native包
这就比较简单了,看了好多的文档都是这么写的,也可以直接从init 的项目里拷过来就好,或者按着官方的来就好
$ npm init
跟着步骤回车就好了,然后好像输入个yes
然后就发现有了一个package.json文件
{ "name": "testRN", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start" }, "author": "", "license": "ISC", "dependencies": { "react": "15.3.1", "react-native": "^0.32.0" } }千万要记住,这个里面的react-native版本一定要和前面gradle的版本一样,不然就出现了那个“Module 0”的版本不一致的错误了,这个错误就看第三步的方法一就好了
然后就是 npm install ,导入react包了
然后就是
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
做一下flow配置 虽然现在不知道是为了什么,但是每个人都这么做
5.添加Js代码
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, ToastAndroid } from 'react-native'; var { NativeModules } = require('react-native'); class MyAwesomeApp extends Component { constructor(props) { super(props); } render() { return( <View > <Text>哈哈哈哈哈哈哈哈</Text> </View> ) } } AppRegistry.registerComponent('MyAwesomeApp', () => MyAwesomeApp);
6.运行Demo
开开reactnative的服务器,npm start
在studio中运行demo,会发现,出现一行“哈哈哈哈”
注:可能会出现java.lang.RuntimeException: Could not get BatchedBridge, make sure your bundle is packaged correctly这个错误,Google就有解决方法,就是在命令行里运行
react-native bundle —platform android —dev false —entry-file index.android.js —bundle-output MyYhao/app/src/main/assets/index.android.bundle —sourcemap-output MyYhao/app/src/main/assets/index.android.map —assets-dest MyYhao/app/src/main/res/react-native bundle —platform android —dev false —entry-file index.android.js —bundle-output MyYhao/app/src/main/assets/index.android.bundle —sourcemap-output MyYhao/app/src/main/assets/index.android.map —assets-dest MyYhao/app/src/main/res/
注意assets的目录,我是在里面直接新建了index.android.bundle和index.android.map两个空文件,然后运行的,会自动往里面写入代码,然后运行就可以了
本人第一次写这些自己的经验,有不足之处,希望大家海涵,因为是后来写的,有些东西可能还是忘记了,如果有碰到什么问题的话,可以直接回复,谢谢
我在自己做的时候,也参考了好多大神的文章,都有很大帮助,他们的文章都在百度的前几个,所以也好找,
谢谢观看
相关文章推荐
- 在Android原生中嵌入React Native,进而React Native调用原生
- React Native嵌入Android原生项目中
- react native 学习笔记----将react native嵌入到Android原生应用
- Android 原生应用嵌入React-Native模块开发-环境配置及填坑记
- 在Android原生中嵌入React Native,进而React Native调用原生
- 在Android原生应用中嵌入ReactNative页面
- Android原生嵌入React Native详解
- React-Native学习之嵌入Android原生项目
- React Native嵌入Android原生项目中(两种方法)
- 如何把React Native嵌入到原生android应用中
- android 原生app嵌入reactnative页面
- React-Native之Android:原生界面与React界面的相互调用
- React native 移植原生android module
- 原生Android项目中集成React native页面
- Android原生应用集成ReactNative坑总结
- React Native移植原生Android
- React Native移植原生Android
- React Native调用Android原生模块
- Android 原生开发、H5、React-Native使用利弊和场景技术分享