首页 > 系统 > Android > 正文

react-native移植到android项目中详细步骤

2019-11-09 14:47:26
字体:
来源:转载
供稿:网友

开篇胡扯:

刚刚过完年假回来上班,公司并没有特别的任务安排。闲来无事,就莫名的开始了人生第一篇的博客之旅吐舌头。本来不想特意将自己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.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 集成到已有项目


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表