React Native学习(Android)——入门配置

本文详细介绍在Android原生项目中集成ReactNative的过程,包括环境搭建、权限配置、主题设置及打包流程,助您快速掌握跨平台开发技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

作为一个移动端开发者,移动端的发展及其迅速,无论你是主动还是被动你都得与时俱进。学习新的移动开发技术是不得不做的事情。当前移动开发主流的东西有React Native和flutter,这两个都是以后的大势所趋,所以闲暇之余对React Native进行一个大致的学习。

React Native的中文官网是真的坑,如果完全按照官网来配置的话,只能是一脸懵逼、两脸懵逼、多脸懵逼,搞了半天结果还是不能用。官网文档虽然存在一些问题,但大部分是正确的配置,经过查看试验官方文档和网上的资源,最后终于实现了在Android原生项目中引入React Native,并打包APK成功,为了以后怕忘记如何操作的特此写下配置文档。

准备

本文针对的是Android原生项目接入RN,前期需要一些准备:

  1. 在Android Studio中新建一个原生的Android项目,例如:ReactNativeApp

  2. 在项目的根目录下新建一个package.json文件,文件内容如下:

     {
       "name": "ReactNativeApp",
       "version": "0.0.1",
       "private": true,
       "scripts": {
         "start": "node node_modules/react-native/local-cli/cli.js start"
       },
       "dependencies": {
         "react": "^16.6.3",
         "react-native": "^0.58.6"
       }
     }
     ----------------------------------------------------------------------------------------------------
     内容介绍:
      - name
     	“name”是一个很重要的属性,可以理解为接入的这个RN的一个标识,在后面会有作用。这个你自己随便写,但需要记住,。
      - version
     	一个版本信息,没啥作用,随便写一个就好,一般是1.0.0或者0.0.1
      - private
     	是否私有,一般是 true
      - scripts
     	一个启动并配置react-native相关信息的命令,这个可以照着写不用修改
      - dependencies
     	顾名思义-依赖,和Android原生中的依赖差不多,这里是添加react和react-native两个依赖,后面的数字是版本号
    
  3. 在项目的根目录打开命令窗口(shift+右键)输入以下指令:

     npm install --save react react-native
    

    等待几分钟加载完成后,这时看输出内容里面会有一个warn,提示你缺少个“react@版本号”,命令台再输入:

     npm add react@版本号
    

    这时整个项目的结构如下:其中node_modules就是刚才加载的文件,comp_demo是我用来存放RN自定义组件的地方,最后将node_modules添加到.gitignore中。

接入

配置Android,使Android可以使用RN相关的东西

  1. 在app目录下的build.gradle添加以下代码:

     android{
     	...
     	defaultConfig {
             ...
             ndk {
                 abiFilters "armeabi-v7a", "x86"
             }
    	}
     }
     dependencies {
     	implementation 'com.android.support:appcompat-v7:27.1.1'
     	...
     	//如果想要指定特定的 React Native 版本,可以用具体的版本号替换 +,当然前提是你从 npm 里下载的是这个版本。一般用+号
     	implementation "com.facebook.react:react-native:+" // From node_modules
     }	
    
  2. 在项目目录下的build.gradle添加以下代码(注意):

     allprojects {
         repositories {
             maven {
     			// 这里不要使用官方的配置,那个有些问题
             	url "$rootDir/node_modules/react-native/android"
             }
         }
     }
    
     在gradle.properties中添加:
     android.useDeprecatedNdk=true
    
  3. 在AndroidManifest.xml文件中添加权限和开发者菜单界面:

     <uses-permission android:name="android.permission.INTERNET" />
    
     <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    
     将APP的主题theme改为:Theme.AppCompat.Light.NoActionBar
    
  4. 在AndroidManifest.xml中添加配置 android:networkSecurityConfig="@xml/network_security_config"

    从Android 9(API级别28)开始,默认情况下禁用明文流量;这可以防止您的应用程序连接到React Native打包程序。这些更改添加了域规则,专门允许对打包器IP的明文流量。

    在res下创建xml文件夹并创建xml文件,添加以下代码:

     <?xml version="1.0" encoding="utf-8"?>
     <network-security-config>
     	<!-- deny cleartext traffic for React Native packager ips in release -->
     	<domain-config cleartextTrafficPermitted="false">
     	    <domain includeSubdomains="false">localhost</domain>
     	    <domain includeSubdomains="false">10.0.2.2</domain>
     	    <domain includeSubdomains="false">10.0.3.2</domain>
     	</domain-config>
     </network-security-config>
    
  5. 在根目录下新建一个空的index.js文件,添加以下代码(如果有RN项目,可以将其复制进来):

     import React from 'react';
     import {AppRegistry, StyleSheet, Text, View} from 'react-native';
     
     class demo extends React.Component {
       render() {
         return (
           <View style={styles.container}>
             <Text style={styles.hello}>Hello, World</Text>
           </View>
         );
       }
     }
     var styles = StyleSheet.create({
       container: {
         flex: 1,
         justifyContent: 'center',
       },
       hello: {
         fontSize: 20,
         textAlign: 'center',
         margin: 10,
       },
     });
     // 这里的第一个参数就是第一步中的name,第二个参数是组件名
     AppRegistry.registerComponent('ReactNativeApp', () => demo);
    
  6. 在Android6.0后需要配置悬浮窗权限

     private final int OVERLAY_PERMISSION_REQ_CODE = 1;  // 任写一个值
     
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
    
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
     	    if (!Settings.canDrawOverlays(this)) {
     	        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
     	                                   Uri.parse("package:" + getPackageName()));
     	        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
     	    }
     	}
     }
    
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                 if (!Settings.canDrawOverlays(this)) {
                     Toast.makeText(this,"没有权限哎",Toast.LENGTH_LONG).show();
                 }
             }
         }
         mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
     }
    
  7. 配置BaseApplication,并在AndroidManifest.xml文件中使用

    <application

    android:name=".MainApplication" />

     public class BaseApplication extends Application implements ReactApplication {
    
         private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
             @Override
             public boolean getUseDeveloperSupport() {
                 return BuildConfig.DEBUG;
             }
     
             @Override
             protected List<ReactPackage> getPackages() {
                 return Arrays.<ReactPackage>asList(
                         new MainReactPackage()
                 );
             }
         };
     
         @Override
         public ReactNativeHost getReactNativeHost() {
             return mReactNativeHost;
         }
     
         @Override
         public void onCreate() {
             super.onCreate();
             SoLoader.init(this, /* native exopackage */ false);
         }
     }
    
  8. 在res/layout中新建activity_main.xml文件

     <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">
     
         <com.facebook.react.ReactRootView
             android:id="@+id/react_root_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"/>
     
     </LinearLayout>
    
  9. 最终的class文件代码如下:

     public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
         private final int OVERLAY_PERMISSION_REQ_CODE = 1;  // 任写一个值
     
         private ReactRootView react_root_view ;
         private ReactInstanceManager mReactInstanceManager;
     
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
     
             initView();
             initPermission();
             initRN();
         }
     
         @Override
         protected void onPause() {
             super.onPause();
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onHostPause(this);
             }
         }
     
         @Override
         protected void onResume() {
             super.onResume();
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onHostResume(this, this);
             }
         }
     
         @Override
         protected void onDestroy() {
             super.onDestroy();
     
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onHostDestroy(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);
         }
     
         private void initRN() {
             mReactInstanceManager = ReactInstanceManager.builder()
                     .setApplication(getApplication())
                     .setBundleAssetName("index.android.bundle")
                     .setJSMainModulePath("index")
                     .addPackage(new MainReactPackage())
                     .setUseDeveloperSupport(BuildConfig.DEBUG)
                     .setInitialLifecycleState(LifecycleState.RESUMED)
                     .build();
             react_root_view.startReactApplication(mReactInstanceManager, "ReactNativeApp", null);
         }
     
         private void initView() {
             react_root_view = (ReactRootView) findViewById(R.id.react_root_view);
         }
     
         private void initPermission() {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                 if (!Settings.canDrawOverlays(this)) {
                     Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                             Uri.parse("package:" + getPackageName()));
                     startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
                 }
             }
         }
     
         @Override
         protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
             if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                     if (!Settings.canDrawOverlays(this)) {
                         // SYSTEM_ALERT_WINDOW permission not granted
                         Log.e("信息:","permission not granted");
                     }
                 }
             }
             mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
         }
     
         @Override
         public void invokeDefaultOnBackPressed() {
             super.onBackPressed();
         }
     }
    
  10. 启动包服务器,在项目根目录下打开命令行输入以下指令:

    npm start
    
  11. 运行APP

打包

  1. 在src/main下创建文件夹assets,并在改文件夹下创建文件index.android.bundle

  2. 在Android Studio的Terminal中输入:

     react-native bundle --platform android --dev false --entry-file index.js --bundle-output ./app/src/main/assets/index.android.bundle --assets-dest ./app/src/main/res/
    
  3. 配置Key store…之后的打包操作和Android一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值