Android + RN 从零搭建

本文详细介绍了如何从零开始,结合Android和ReactNative进行混合应用开发,包括JDK、Node.js、AndroidStudio设置、依赖管理、配置ReactNative环境、添加RN组件和调试步骤。
摘要由CSDN通过智能技术生成

Android + RN 从零搭建

简介

简要介绍如何从零搭建Android + RN的混合开发APP

官网

React Native 官网

必要安装

  1. JDK
    我用的是JDK17,别上Oracle上下,慢的很,用下面这个链接JDK
  2. nodejs
    这个直接百度下载就行,我用的版本是18.20.0
  3. 编译器 AS + WebStorm

搭建流程

安装必要的包

# 使用nrm工具切换淘宝源
npx nrm use taobao

# 安装yarn,快速装包
npm install -g yarn

新建Android工程

直接走AS new Project就行

添加maven仓库

直接走google jcenter下载巨慢,而且容易被墙
新版AS的结构,maven仓库都是配置在settings里的
每个仓库里都加上这俩maven就行

maven{   
    allowInsecureProtocol true   
    url  'http://maven.aliyun.com/nexus/content/repositories/central/'}
maven{   
    allowInsecureProtocol true      
    url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
添加RN依赖

def jscFlavor = 'org.webkit:android-jsc:+'

dependencies {
    implementation "com.facebook.react:react-android:0.73.6"

    if (hermesEnabled.toBoolean()) {        
        implementation("com.facebook.react:hermes-android:0.73.6")
    } else {   
        implementation jscFlavor
    }
}

app下的build.gradle里添加上面这些依赖,其中唯一没有的hermesEnabled这个是配置在gradle.properties里面的 hermesEnabled=true

对于上面这些依赖,react-android这个就不用说了,RN的依赖,而对于下面hermes那坨也一定要加上,否则会有一个so库的编译报错

Manifest

清单文件中首先需要有网络访问权限INTERNET,其次为了能使用RN摇一摇,需要添加

此外,为了支持本地调试,首先需要支持http
android:usesCleartextTraffic=“true”
还有一点,如果你创建的项目是Compose的Android项目,想着把主题换成NoActionBar

activity中添加RNView并初始化
package 
com.tang.rntestimport android.os.Bundle
import android.view.KeyEvent
import androidx.appcompat.app.AppCompatActivity
import com.facebook.react.ReactInstanceManager
import com.facebook.react.ReactPackageimport com.facebook.react.ReactRootView
import com.facebook.react.common.LifecycleState
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler
import com.facebook.react.shell.MainReactPackage
import com.facebook.soloader.SoLoader

class MainActivity : AppCompatActivity(), DefaultHardwareBackBtnHandler {    
    private var mReactRootView: ReactRootView? = null   
    private var mReactInstanceManager: ReactInstanceManager? = null    
    
    override fun onCreate(savedInstanceState: Bundle?) {       
        super.onCreate(savedInstanceState)      
        SoLoader.init(this, false)        
        val packages = listOf<ReactPackage>(MainReactPackage())        
        mReactRootView = ReactRootView(this)        
        mReactInstanceManager = ReactInstanceManager.builder()            
        .setApplication(application)            
        .setCurrentActivity(this)            
        .setBundleAssetName("index.android.bundle")           
        .setJSMainModulePath("index")            
        .addPackages(packages)            
        .setUseDeveloperSupport(true)            
        .setInitialLifecycleState(LifecycleState.RESUMED)           
        .build()     
        

        mReactRootView?.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);    

        setContentView(mReactRootView)  
    }   

    override fun invokeDefaultOnBackPressed() {   
        super.onBackPressed()   
    }  
    
    override fun onPause() {    
        super.onPause()     
        if (mReactInstanceManager != null) {   
            mReactInstanceManager!!.onHostPause(this) 
        }   
    }    
    override fun onResume() {  
        super.onResume()       
        if (mReactInstanceManager != null) {    
            mReactInstanceManager!!.onHostResume(this, this)     
        }  
    }   
    override fun onDestroy() {    
        super.onDestroy()       
        if (mReactInstanceManager != null) {    
            mReactInstanceManager!!.onHostDestroy(this)   
        }      
        if (mReactRootView != null) {      
            mReactRootView!!.unmountReactApplication()      
        }   
    }    
    override fun onBackPressed() {    
        if (mReactInstanceManager != null) {     
            mReactInstanceManager!!.onBackPressed()      
        } else {         
            super.onBackPressed()    
        }   
    }   
    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {  
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {     
            mReactInstanceManager!!.showDevOptionsDialog()        
            return true   
        }       
        return super.onKeyUp(keyCode, event)   
    }
}

这块呢,没什么技术含量了,基本都是官网的代码直接荡过来的。
简单来说就是创建了一个ReactRootView,并将其设置为Activity的content,然后对这个ReactRootView做了一些配置,其中要注意的一个点就是setJSMainModulePath方法的参数就对应了要启动RN的首页为index.js

Run

到这里就可以先运行原生这块了,如果一切正常不闪退,恭喜你完成了一半,虽然这回展示的页面是个红屏页

OK,原生这块基本上是都搞定了,下面就是RN的部分了

创建RN工程

注意,这块不要从WebStorm直接新建,严格按照如下流程走

新建一个目录,用于存放你的RN工程如RNTest,并在其内部新建一个android子文件夹

当前目录结构:

RNTest
    /android

然后把刚才建好的Android工程全部都挪到这个/android目录下

打开RN工程,并添加package.json

用WebStorm打开这个RNTest,并新建package.json
添加如下语句:

{ 
    "name": "MyReactNativeApp",  
    "version": "0.0.1", 
    "private": true,
    "scripts": {   
        "start": "react-native start" 
    }, 
    "dependencies": { 
        "@react-native/metro-config": "^0.75.0-main",  
        "metro-config": "^0.80.8",    
        "react": "^18.2.0",   
        "react-native": "0.73.6" 
    }
}

当前目录:

RNTest
    /android
    package.json

然后直接在命令行里yarn 一下,所有该装的包就都装好了
当前目录:

RNTest
    /android
    /node_modules
    package.json
    package-lock.json
    yarn.lock

注意这个name必须和Android工程里你配置名称一样

新增文件metro.config.js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

const config = {};module.exports = mergeConfig(getDefaultConfig(__dirname), config);

这个文件也是默认的
当前目录:

RNTest
    /android
    /node_modules
    metro.config.js
    package.json
    package-lock.json
    yarn.lock
新增入口文件index.js

这个里随便加一点View,能展示出来看效果就行
官方提供的:

import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';

const HelloWorld = () => {   
    return (       
        <View style={styles.container}>     
            <Text style={styles.hello}>Hello, World</Text>    
        </View>  
    );
};

const styles = StyleSheet.create({    
    container: {      
        flex: 1,       
        justifyContent: 'center',   
    },    
    hello: {    
        fontSize: 20,       
        textAlign: 'center',      
        margin: 10,    
    },
});
AppRegistry.registerComponent(  
    'MyReactNativeApp',   
    () => HelloWorld,
);

这里就是简单展示了一个文本控件
当前目录:

RNTest
    /android
    /node_modules
    index.js
    metro.config.js
    package.json
    package-lock.json
    yarn.lock

启动服务

在webStorm的命令行里,键入yarn start --port=8081, 这样就能启动一个端口号为8081的RN本地服务

连接服务

adb手机直连

cmd打开终端命令行,映射端口号到电脑

adb reverse tcp:8081 tcp:8081

然后摇一摇手机,晃出菜单,点击settings选择debug server host,输入127.0.0.1:8081

局域网连接

电脑和手机连接同一局域网,并通过ipconfig看到ipv4地址为XXX.XXX.XXX.XXX
然后摇一摇手机,晃出菜单,点击settings选择debug server host,输入XXX.XXX.XXX.XXX:8081

重新加载

webStorm的命令行里输入r,或者摇一摇手机,晃出菜单,点击reload,这个时候看下WebStorm的终端里有一个bundle加载的进度,等进度加载完成,你的RN页面也将显示出来。大功告成!!

  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值