混合开发架构|Android工程集成React Native、Flutter、ReactJs
架构设计说明
该篇文章,介绍并记录在大前端混合架构开发中的重要细节和流程。通过在安卓原生工程中集成两大主流混合框架React Native、Flutter,以及ReactJs[Vue],集成三类模块module的架构的混合设计。并分别在这些主流技术栈的业务创作中,自己造轮子、使用新颖架构设计及核心技术去实现。并在编码过程中还会创造常用工具,沉浸式状态栏、底部导航栏、
tab1 | tab2 | tab3 | tab4 | tab5 |
---|
仿招商银行首页 | 仿即时通讯 | 仿工商银行首页 | 仿抖音我的页面 | 仿唯品会分类 |
在原生工程中创建一个首页,在首页中使用五个TAB 。
TAB1 ,使用原生Java+Kotlin编码,仿招商银行首页,使用优秀架构设计,完成列表各个模块的独立解耦。TAB2 ,使用原生Java+Kotlin编码,仿微信,通过Android Socket实现IM的即时通讯。TAB3 ,使用React Native编码,仿工商银行首页。TAB4 ,使用Flutter编码,仿抖音我的页面。TAB5 ,使用ReactJs编码,仿唯品会分类页面。
创建安卓原生工程
Android Studio版本 | gradle 插件版本 | gradle 版本 | JDK 版本 | 其他 |
---|
3.6 | 3.6.0 | gradle-5.6.4-all.zip | JDK11 | compileSdkVersion 31、buildToolsVersion “30.0.0” 、minSdkVersion 21、targetSdkVersion 30 |
创建Flutter
Android Studio版本 | gradle 插件版本 | gradle 版本 | JDK 版本 | 其他 |
---|
3.6 | 3.6.0 | gradle-5.6.4-all.zip | JDK11 | compileSdkVersion 31、buildToolsVersion “30.0.0” 、minSdkVersion 21、targetSdkVersion 30 |
集成嵌入原生工程
详尽集成介绍,请移步查看
创建React Native
与创建Flutter相比较,React Native工程创建时,复杂很多。创建时候会遇到创建失败问题,成功创建后,启动Metro服务也会遇到报错问题。而这些问题都与nodejs版本 ,React Naitve版本 有关。请详细阅读官方搭建环境的文档,
React Native 创建指令:npx react-native init hibrid_rn --version 0.67.0 Metro服务启动指令:npx react-native start Android apk 编译安装指令:yarn android
如下报错信息,则是node版本号使用不当导致~ /node_modules/@react-native-community/cli/build/commands/doctor/healthchecks/index.js:48 } catch {} ^ SyntaxError: Unexpected token { at createScript (vm.js:80:10) at Object.runInThisContext (vm.js:139:10) at Module._compile (module.js:617:28) at Object.Module._extensions…js (module.js:664:10) … … …
集成嵌入原生工程
project.ext.react = [
entryFile : "index.android.js",
enableHermes: false,
bundleInDebug:true,
bundleInBeta:true
]
def enableHermes = project.ext.react.get("enableHermes", false);
def jscFlavor = 'org.webkit:android-jsc:+'
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
......
if (enableHermes) {
def hermesPath = "../../hibrid_rn/node_modules/hermesvm/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
implementation "com.facebook.react:react-native:+"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
}
allprojects {
repositories {
......
maven {
url "$rootDir/../hibrid_rn/node_modules/react-native/android"
}
maven {
url("$rootDir/../hibrid_rn/node_modules/jsc-android/dist")
}
}
}
参数字段说明:
entryFile : "index.android.js" ,表示配置加载安卓资源入口文件名称。def hermesPath = "../../hibrid_rn/node_modules/hermesvm/android/" ,表示当enableHermes==true 时,引入执行引擎Hermes。否则,使用JavaScriptCore执行引擎。
Hermes 是一个可选的 React Native 功能。如果要启用Hermes,需要确保 React Native项目的版本在0.60.2版本 以上,并且还需要对android/app/build.gradle 做以下更改。我们这里配置enableHermes: false
project.ext.react = [
entryFile: "index.js",
enableHermes: true
]
RN集成后,启动报错
在原生工程中集成了RN之后,将React Native作为原生工程Activity下LayoutView的一部分,测试集成状态。发现从Native启动React Native报以下错误~
ReactNative: Exception in native call java.lang.RuntimeException: Unable to load script. Make sure you're either running Metro (run 'npx react-native start') or that your bundle 'rn/index.android.bundle' is packaged correctly for release.
报错信息说,Metro服务未启动,或者说找不到bundle资源包。而事实是当前Metro服务已启动,且直接启动React Native工程是OK的。对此寻到以下两种解决方案 :
- 对当前
React Native 工程代码进行打包,并将打包后的bundle资源 拷贝到Native工程的/main/assets/rn 目录下。然后在Native运行则无问题。 - VSCode终端执行打包指令:
react-native bundle --platform android --dev false --entry-file index.js --bundle-output ../HybridArcPro/app/src/main/assets/rn/index.android.bundle --assets-dest ../HybridArcPro/app/src/main/res/ - 非打包处理。需要对Native和React Native端同时进行配置。①对安装的debug包APP配置服务IP和端口号。②配置网络权限,
application标签 中配置 tools:targetApi="28" android:allowBackup="true" 。③启动Metro服务。
底部导航栏架构设计
使用java语言,自定义首页底部导航栏布局控件(下图实现效果+导航源码),自定义UML介绍~
TabBtnLayoutBottomNav 底部导航栏布局自定义View。继承自FrameLayout,实现自接口ITabLayout。底部导航栏布局,内部摆放TabBtnBottom ,TabBtnBottom 底部导航栏布局中的单个Tab。继承自RelativeLayout,实现自I接口ITab(ITab继承了点击事件的监听接口OnTabSelectedListener)。TabBtnLayoutBottomNav 内部封装单个Tab集合List<OnTabSelectedListener> (包含所有TabBtnBottom和TabBtnLayoutBottomNav添加的监听OnTabSelectedListener),当用户点击Tab时,点击事件通过TabBtnBottom.setOnClickListener 触发集合List的遍历,此时将点击事件传递给每个TabBtnBottomz,同时TabBtnLayoutBottomNav添加的监听回调。由此单个Tab和TabBtnLayoutBottomNav产生了点击事件的关联,并能为集成fragment点击切换显示做下伏笔。 TabBtnFragmentLayout ,显示fragment页面的**自定义布局控件**,放在布局文件TabBtnLayoutBottomNav中。由TabBtnLayoutBottomNav添加的监听回调index,方法setCurrentItem 获得指示并显示相应fragment页面。TabBtnFragmentAdapter ,显示fragment页面的适配器类。具体指示显示fragment页面逻辑,实现在方法instantiateItem 中。
原生仿招商银行首页
原生Android Socket 即时通讯
React Native仿工商银行首页
原生传递props初始对象,RN使用
原生与RN通信
Flutter仿抖音我的页面
原生与Flutter通信
ReactJs仿唯品会分类页面
详尽开发介绍,请移步查看
工程源码地址
点击进入仓库,查看工程源码
|