Android项目接入ReactNative
Android项目接入ReactNative:
前言
1、本次接入的RN版本为0.60.4
2、android项目gradle编译版本为3.4.1,编译工具buildToolsVersion为28.0.3
3、如果是原生接入rn,在ios端也需要进行处理,请参考官方资料。
4、官方文档,点击可以切换android和ios文档,如下图
官网android集成步骤
第一步:创建项目
创建RN空项目,把整个android项目复制进rn项目下的android目录下
第二步:修改项目级build
修改android项目级别的build.gradle中allprojects下添加代码:
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
第三步:修改app下build
在app下的build.gradle的dependencies下添加依赖:
//指定版本,版本号需要和你package.json中的版本号一致
implementation "com.facebook.react:react-native:0.59.4" // From node_modules
当rn版本为0.60以上时,可能会报错,
Manifest merger failed : Attribute application@appComponentFactory value
这时需要把android项目依赖库改成AndroidX库,通过studio一键转换,butterknife记得升级到最新的10.0,不然是无法支持x库,错误如下:
The given artifact contains a string literal with a package reference 'android.support.v4.content' that cannot be safely rewritten. Libraries using reflection such as annotation processors need to be updated manually to add support for androidx.
第四步:实现application
程序的Application实现ReactApplication的接口:
public class MainApplication extends MultiDexApplication implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
// @Override
// protected String getJSBundleFile() {
// return CodePush.getJSBundleFile();
// }
@Override
public boolean getUseDeveloperSupport() {
LogUtil.e("getUseDeveloperSupport: BuildConfig.DEBUG===" + BuildConfig.DEBUG);
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNGestureHandlerPackage()
// new RNGestureHandlerPackage(),
// new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG)
// new UpdatePackage(),
// new BlurViewPackage(),
// new OrientationPackage(),
// new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG)
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
}
第五步:创建入口activity
创建RN的入口Activity,继承ReactActivity(也可以继承AppCompatActivity,自己实现各种生命周期),如下:
public class ReactNativeMainActivity extends ReactActivity {
public static void start(Context context) {
Intent starter = new Intent(context, ReactNativeMainActivity.class);
context.startActivity(starter);
}
@Nullable
@Override
protected String getMainComponentName() {
return "NativeAndroid";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(ReactNativeMainActivity.this);
}
};
}
}
注意
getMainComponentName() 这个方法返回的应该和index.js中返回的appName应该一致,如下:
AppRegistry.registerComponent('NativeAndroid', () => App);
第六步:
android studio运行,并在rn项目目录下打开命令窗口开启服务器(指令:npm start),原生使用intent跳转进入rn的activity,等待命令窗口加载JS文件。
集成完成之后就是一个普通的rn工程,如下图
rn工程接入过程中遇到的问题
1、打开RN界面运行闪退,报错:
java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so
出现此问题基本是集成的0.60.以上的版本导致的,需要修改2个地方:
项目下的build,需要添加jsc
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
整体如图:
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
google()
jcenter()
}
}
app下的build需要添加:
//在外层添加
def useIntlJsc = false
//在依赖中添加以下内容
if (useIntlJsc) {
implementation 'org.webkit:android-jsc-intl:+'
} else {
implementation 'org.webkit:android-jsc:+'
}
2、react-native run-android命令报错
:Task 'installDebug' not found in project ':app'.
原因:一般都是多渠道打包导致的
解决方式:
第一种:
react-native run-android --variant ogdfRelease
react-native run-android --variant assembleDebug
第二种:
把app下的build.gradle还原为标准的格式,在build.gradle中不要使用runtime,如:
productFlavors {
runtime {
applicationId "com.df.bwtnative.${station_code}"
//applicationId "com.op.psit300"
resValue "string", "app_name", app_name
resValue "string", "station_code", station_code
}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
总结
1、 集成过程总共分为6步(copy原始android项目、修改项目build、修改app的build、修改application、新增rn入口activity)
2、 android接入rn的老版本是在android工程下创建index.js入口,然后安装node库,整体是以android工程为主导,但rn新版本的接入是把android工程复制到rn下的android目录,整体以rn工程为主导。从开发角度来说,新版本接入更利于android和rn开发的分工。
3、 集成最新的rn(0.60.4为例)版本需要支持androidX库,所以需要在android工程中修改很多包路径,虽然有studio的一键转换工具,但是从项目安全角度来说,从代码审阅、编译、打包、业务等都需要进行测试一遍,防止隐藏的bug
4、 原生项目接入rn,android和ios端都需要进行集成,原生代码不共用,但RN代码共用。不确定是否影响ios上架,但单纯的rn项目是可以上架成功。