React-Native移植-Android
简介参考链接: 由于公司业务需要,部分模块需要将native代码转移到react-native,并且由于是已有项目,所以我这里单独把react-native移植到项目来,移植的过程中遇到了一些问题,这里也记录了下。 网上的一些教程资料都不是很全,而且一些关键的步骤说的都不是很详细,这里我们从零开始。 还有就是环境配置这里不讲了,都是很基础的东西! 新建一个Android项目这里我们新建一个ReactNativeProject,初始化目录结构如下: 引入React-Native在你的app目录下的build.gradle加入react-native依赖,我加入的是最新版本的0.20.1 compile 'com.facebook.react:react-native:0.20.1' 然后在AndroidManifest.xml加入访问网络权限,当然一般已经项目都有这个权限,如果有这一步可以忽略 <uses-permission android:name="android.permission.INTERNET" /> 为了让项目支持调试RN,需要在AndroidManifest.xml里面加入RN的DevSettingsActivity,如下: <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> 这样真机晃动手机或者点击Menu菜单就会打开相关的调试页面,如图下所示: 这里部署完后,还有一个坑,就是React-Native对编译版本和最小编译版本都有要求,它需要app的build.gradle文件的compileSdkVersion为23,minSdkVersion为16,因为我们项目要求最低版本为15甚至更低,这里需要在app的AndroidManifest.xml加入 <uses-sdk tools:overrideLibrary="com.facebook.react" /> 加入基础的Android原生代码和JS代码我们新建一个MyReactActivity,完整代码贴下 public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler { private ReactRootView mReactRootView; private ReactInstanceManager mReactInstanceManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_react); mReactRootView = (ReactRootView) findViewById(R.id.react_root); 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,"ReactNativeProject",null); } @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } @Override protected void onPause() { super.onPause(); if (mReactInstanceManager != null) { mReactInstanceManager.onPause(); } } @Override protected void onResume() { super.onResume(); if (mReactInstanceManager != null) { mReactInstanceManager.onResume(this,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); } } 因为ReactRootView本身就是一个FrameLayout,我没有按官网来直接new一个,而是直接把它放到布局activity_my_react.xml里面了,代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.hhl.reactnativeproject.MyReactActivity"> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:gravity="center" android:text="我是本地控件TextView" android:textSize="20sp" /> <com.facebook.react.ReactRootView android:id="@+id/react_root" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> 这里需要强调一下下,Activity里面有两个方法,setBundleAssetName和setJSMainModuleName,其中setBundleAssetName间接调用了setJSBundleFile,而setJSBundleFile就是我们以后要讲的热修复的关键;而setJSMainModuleName设置的就是index.android.js的名字,这个可以更改目录位置。 Android代码加完了,开始加入JS代码,这里我们在项目根目录下,也就是我们的ReactNativeProject目录下加入index.android.js文件和package.json文件,index.android.js文件简单代码如下: 'use strict'; import React,{ Text,View } from 'react-native'; class ReactNativeProject extends React.Component { render() { return ( <View style={styles.container}> <Text style={styles.hello}>Hello,World</Text> <Text>测试ReactNative</Text> </View> ) } } var styles = React.StyleSheet.create({ container: { flex: 1,justifyContent: 'center',},hello: { fontSize: 20,textAlign: 'center',margin: 10,}); React.AppRegistry.registerComponent('ReactNativeProject',() => ReactNativeProject); package.json代码如下: { "name": "ReactNativeProject","version": "1.0.0","description": "demo","main": "index.js","scripts": { "test": "echo "Error: no test specified" && exit 1","start": "node node_modules/react-native/local-cli/cli.js start" },"author": "hanhailong","license": "ISC","dependencies": { "react": "^0.14.8","react-native": "^0.24.1" } } 项目配置运行调试在ReactNativeProject目录下执行如下命令 $ npm init $ npm install --save react-native $ curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig npm init命令可以不用执行,它如要用来生成package.json文件,前面我们已经创建过了,npm install –save react-native执行后会在目录下面生成node_modules文件夹并添加react-native的npm依赖 首先启动RN的npm本地服务: $ npm start 启动后如下: 在MainActivity里面我们加入跳转到MyReactActivity的代码, Intent intent = new Intent(MainActivity.this,MyReactActivity.class); startActivity(intent); 项目结构图项目运行效果最后我们运行项目,运行效果图如下: 编译可能遇到的问题Caused by: java.lang.IllegalAccessError: tried to access method android.support.v4.net.ConnectivityManagerCompat.:(Lcom/facebook/react/bridge/ReactApplicationContext;)V from class com.facebook.react.modules.netinfo.NetInfoModule我的项目的appcompat的版本是23.2.1,改成23.0.1就好了 compile 'com.android.support:appcompat-v7:23.0.1' Demo下载ReactNativeProject 下一节讲解RN热更新下一节我们将讲解RN的热更新,敬请期待!!! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |