react-native移植到android项目中详细步骤
2017-02-10 16:38
447 查看
开篇胡扯:
刚刚过完年假回来上班,公司并没有特别的任务安排。闲来无事,就莫名的开始了人生第一篇的博客之旅。本来不想特意将自己get到的东西写到博客上。
一是担心自己的经验不够,写了害怕误人子弟;
二是自己可以随便在云笔记上写自己懂的东西,不必花费很多时间在斟酌字句上,担心有什么疏漏。
好了,既然决定写了就认真的分享下(免得真的误人),自己也再次巩固所学到的,还可以无意之中的帮助别人,何乐不为!
回归正题,对于react-native,去年就开始稍微了解过,尝试写过些小demo,但由于自己的懒惰就没有去尝试性的往下面继续研究了,主要是公司还没用到,自己就想偷个懒。恰巧昨天看到鸿神推送的关于react-native的文章,于是就下定决心开始重拾起来。下面就开始说说个人昨天一天对于rn集成到android项目中实践心得吧,希望各位给出意见!
前提rn的环境配置完毕(以下说的拷贝是react-native init之后的工程里的文件)
第一步:
进入android工程根目录使用npm init命令创建package.json文件(或者将生成好的rn项目拷贝过去)千万要记住,这个里面的react-native版本一定要和android工程里gradle配置的版本一样,不然就出现了那个“Module 0”的版本不一致的错误了。第二步:
在android工程的根目录使用npm install -save react react-native下载源文件,最后会生成一个node_modules文件夹(当然也可以拷贝原来的)第三步:
拷贝或者下载.flowconfig文件(下载链接https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig),主要是给folw用的,用来做静态代码检查,下载完后放在android的根目录下即可。第四步:
配置Android项目react-native依赖库,版本号一定要和本地rn的版本一致第五步:
配置react-native本地代码路径,本步骤是制定Android-studio编译react-native时用制定路径下的代码,大致这个意思。这里添加是在根目录下的build.gradle中修改,放在在allprojects节点下。截图如下:同步工程在External Libraries看到这个匹配的版本的依赖包就说明成功了。
第六步:
修改package.json文件,修改信息如下:{ "name": "myapplication", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "bundle-android":"react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output MyApplication/app/src/main/assets/index.android.bundle --sourcemap-output MyApplication/app/src/main/assets/index.android.map --assets-dest MyApplication/app/src/main/res/" }, "author": "0", "license": "ISC", "dependencies": { "react": "^15.3. b7e6 1", "react-native": "^0.33.0" } }
name是工程名字字母都小写,scripts一定要根据自己的实际配置不然会报错,dependencies按照自己的版本来修改(最好参照原生的react-native的package.json)
第七步:
创建原生安卓类,作为加载rn容器,再将index.android.js(rn的核心代码文件)文件直接放在android项目根目录就行或者自己创建添加如下代码:import React,{Component} from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; class HelloWorld extends React.Component { render() { return ( <View style={styles.container}> <Text style={styles.hello}>这是React-Native组件</Text> </View> ) } } var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', backgroundColor:'#ccc', }, hello: { fontSize: 20, color: '#fff', textAlign: 'center', margin: 10, }, }); //注意这里的reactdemo哦 AppRegistry.registerComponent('reactdemo', () => HelloWorld);
再创建一个ReactActivity
public class ReactActivity extends Activity implements DefaultHardwareBackBtnHandler { private ReactRootView mReactRootView; private ReactInstanceManager mReactInstanceManager; private LinearLayout ll; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myreactdemo); 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(); //reactdemo这个名字要与package.json、以及react-native中index.android.js中的项目名要一致,否则会出错。 mReactRootView.startReactApplication(mReactInstanceManager, "reactdemo", null); ll= (LinearLayout) findViewById(R.id.ll); ll.addView(mReactRootView); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostResume(this, this); } } @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostPause(MyReactActivity.this); } } @Override protected void onDestroy() { super.onDestroy(); if (mReactInstanceManager != null) { mReactInstanceManager.onHostDestroy(MyReactActivity.this); } } @Override public void onBackPressed() { if (mReactInstanceManager != null) { mReactInstanceManager.onBackPressed(); } else { super.onBackPressed(); } } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } }再在MainActivity里添加点击事件跳入ReactActivity
findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (Build.VERSION.SDK_INT>=23){ if (!Settings.canDrawOverlays(MainActivity.this)){ startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)); return; }else{ } }else{ //绘UI代码,这里android6.0以下的系统可以直接绘出即可 } startActivity(new Intent(MainActivity.this,ReactActivity.class)); } });
第八步:
修改AndroidManifest.xml配置文件如下:<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
<activity android:name=".MyReactActivity"/> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
第九步:
打开cmd进入到android的目录下,运行react-native start ,启动服务,再运行android项目,就可以看见一部分是android原生控件,一部分是rn控件常见错误
java.lang.IllegalAccessError: Method 'void android.support.v4.net.ConnectivityManagerCompat.()' is inaccessible to class 'com.f
acebook.react.modules.netinfo.NetInfoModule' (declaration of 'com.facebook.react.modules.netinfo.NetInfoModule' appears in
/data/app/package.name-2/base.apk)
解决办法:(老外也遇到了这样的问题https://github.com/facebook/react-native/issues/6152#issuecomment-200759453)在项目下修改以下的文件内容:
.gitignore(在该文件里添加排除项,node_modules/ 和 npm-debug.log)
app/build.gradle (将 'com.android.support:appcompat-v7:24.2.1' 改为 'com.android.support:appcompat-v7:23.0.1')
gradle.properties (在文件末尾添加,android.useDeprecatedNdk=true)
红屏问题"Could not get BatchedBridge, make sure your bundle is packaged correctly"解决方法: 主要就只遇到这一个问题, 更改ip和port没有解决了, 后来在package.json中的"scripts"中添加"bundle-android":"react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output 工程名/app/src/main/assets/index.android.bundle --sourcemap-output 工程名/app/src/main/assets/index.android.map --assets-dest 工程名/app/src/main/res/",如果没有assets目录,手动添加下,不过运行时没有效果, 在cmd中手动执行下(去掉命令的工程名如果在根路径下执行命令), assets目录中会多出几个文件, 即可解决这个问题
参考资料:
如何把React Native嵌入到原生android应用中
React Native 集成到已有项目
相关文章推荐
- 【React Native开发】React Native移植原生Android项目(Mac用)
- 将React Native整合进Android项目超详细图文教程
- 将ReactNative项目整合到android项目中步骤
- 【React Native开发】React Native移植原生Android项目(4)
- 【React Native开发】React Native移植原生Android项目(4)
- react-native for android windows开发环境搭建详细记录
- Android Eclipse下工程移植到Android Studio详细步骤
- React Native移植到原生iOS平台项目
- React Native for android 项目驱动教程
- AndroidStudio项目提交(更新)到github最详细步骤
- 怎么运行别人的React-Native项目(android端)
- React-Native移植-Android
- AndroidStudio项目提交(更新)到github最详细步骤
- 从零开始的Android新项目10 - React Native & Redux
- React native 移植原生android module
- 在Windows上将ReactNative集成到现有的Android项目
- 在Windows上将ReactNative集成到现有的Android项目
- AndroidStudio项目提交(更新)到github最详细步骤
- AndroidStudio项目交付(更新)到github最详细步骤