reactnative入门及一些踩过的坑(代码片段)

Coding_the_world Coding_the_world     2022-12-03     275

关键词:

 

集成步骤也可以参考react-native中文网,但是中间还是会遇到特殊情况,上面没有说明

一、安装node(不然npm的时候会报“不是内部命令”)

  npm是nodejs的一个子内容,所以要使用npm,就一定要先安装nodejs。安装方法其实没啥好说的,完全傻瓜化的,官网上下载安装包,一路next就完了。

  安装完了如何判断自己是否安装成功呢?

  你只需要在命令行窗口中输入命令:  

node -v    //查看node 的版本号

npm -v   //查看npm的版本号

二、安装react-native

执行以下命令,进行安装

npm install -g react-native-cli

三、创建package.json

在项目根目录下创建一个名为package.json。可以直接创建,也可以使用npm init创建


  "name": "MyRNTest",
  "version": "1.0.0",
  "description": "",
  "scripts": 
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  ,
  "dependencies": 
    "babel-preset-react-native": "^4.0.0",
    "react": "^16.0.0-alpha.6",
    "react-native": "^0.55.0",
    "react-native-update": "^4.0.6"
  ,
  "devDependencies": 
    "babel-jest": "21.2.0",
    "jest": "21.2.1",
    "react-test-renderer": "16.0.0-alpha.6"
  ,
  "jest": 
    "preset": "react-native"
  

四、配置 maven

在项目的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口,必须写在 "allprojects" 代码块中:

allprojects 
    repositories 
        maven 
            //url "$rootDir/node_modules/react-native/android"如果路径这样写,会下载最新版本RN
            url "$rootDir/../node_modules/react-native/android"
        
        ...
    
    ...

在你的 app 中 build.gradle 文件中添加 React Native 依赖

dependencies 
    implementation 'com.android.support:appcompat-v7:27.1.1'
    ...
    //如果要限制版本:implementation("com.facebook.react:react-native:0.55.0")  force = true 
    implementation "com.facebook.react:react-native:+" 
defaultConfig 
        ...

        ndk 
            abiFilters "armeabi-v7a", "x86"
        

    
    packagingOptions 
        exclude "lib/arm64-v8a/librealm-jni.so"
    

    //解决jsr302与jsr305版本冲突
    configurations.all 
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
    

五、配置权限

在 AndroidManifest.xml 清单文件中声明权限:

//网络权限
<uses-permission android:name="android.permission.INTERNET" />
//弹框权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

 

如果需要访问 DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

六、RN组件

1.首先在项目根目录中创建一个空的index.js文件。(注意在 0.49 版本之前是 index.android.js 文件)

index.js是 React Native 应用在 Android 上的入口文件。而且它是不可或缺的!

2. 添加你自己的 React Native 代码,简单例子,网上都有,我这里举一个多入口引用的例子

import React,  Component  from 'react';
import 
  AppRegistry,
  Text,
    View
 from 'react-native';

import MyFirstRN from './myfirstrn'//填写对应myfirstrn.js路径,我这里在根目录下
import MySecondRN from './mysecondrn'//填写对应mysecondrn.js路径,我这里在根目录下

//注册:第一个字段可以认为是为RN中的页面添加映射,需要和你Activity中注册的名称一致
AppRegistry.registerComponent('MyRNActivity', () => MyFirstRN);
AppRegistry.registerComponent('MyRNActivity2', () => MySecondRN);

注意,一个RN页面只能对应注册一个名称,不然会被覆盖,例如:

AppRegistry.registerComponent('MyRNActivity', () => MyFirstRN);
AppRegistry.registerComponent('MyRNActivity2', () => MyFirstRN);
//此时,MyRNActivity2会对应MyFirstRN,MyRNActivity不会对应,你的Activity中如果注册MyRNActivity
//则会报红屏MyRNActivity未注册

myfirstrn.js和mysecondrn.js简单写了下,需要注意里面的class需要用export default修饰,不然import时会报错

import React,  Component  from 'react';
import 
  AppRegistry,
  Text,
  View
 from 'react-native';

export default class MyFirstRN extends Component 
  render() 
      return (
        <View >
          <Text >
            我是 MyFirstRN ReactNative//例子里MySecondRN就这里改了下
          </Text>
        </View>
      );
    
  

七、悬浮框权限(仅开发时用于看红屏报错)

如果你的应用会运行在 Android 6.0(API level 23)或更高版本,请确保你在开发版本中有打开悬浮窗(overlay)权限。你可以在代码中使用Settings.canDrawOverlays(this);来检查。之所以需要这一权限,是因为我们会把开发中的报错显示在悬浮窗中(仅在开发阶段需要)。在 Android 6.0(API level 23)中用户需要手动同意授权。具体请求授权的做法是在onCreate()中添加如下代码。其中OVERLAY_PERMISSION_REQ_CODE是用于回传授权结果的字段。

private final int OVERLAY_PERMISSION_REQ_CODE = 1;  // 任写一个值

...

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)) 
                // SYSTEM_ALERT_WINDOW permission not granted
            
        
    
    mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );

八、调用RN页面

有两种方法:

1.你的Activity继承ReactActivity

public class MyRNActivity2 extends ReactActivity 
//public class MyRNActivity2 extends BaseReactActivity 
    @Nullable
    @Override
    protected String getMainComponentName() 
        return "MyRNActivity2";
    

2.你的Activity实现 DefaultHardwareBackBtnHandler 接口

public class MyRNActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler 

    private ReactRootView mReactRootView;

    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        
        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()

                .setApplication(getApplication())

                .setCurrentActivity(this)

                .setBundleAssetName("index.android.bundle")

                .setJSMainModulePath("index.android")//xxx.js
                .addPackage(new MainReactPackage())

                .setUseDeveloperSupport(true)

                .setInitialLifecycleState(LifecycleState.RESUMED)

                .build();

        // 注意这里的MyReactNativeApp必须对应“index.android.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "MyRNActivity", null);
        setContentView(mReactRootView);
    

    @Override
    public void invokeDefaultOnBackPressed() 
        if(mReactInstanceManager!=null)
            mReactInstanceManager.onBackPressed();
        else
            super.onBackPressed();
        
    
    @Override
    protected void onResume() 
        super.onResume();
        if(mReactInstanceManager!=null)
            mReactInstanceManager.onHostResume(this,this);
        

    


    @Override
    protected void onPause() 
        super.onPause();

        if(mReactInstanceManager!=null)
            mReactInstanceManager.onHostPause(this);
        
    


    @Override
    protected void onDestroy() 
        super.onDestroy();

        if(mReactInstanceManager!=null)
            mReactInstanceManager.onHostDestroy(this);
        
    

另外:如果是原生和RN混合页面,可以在布局中添加RN控件,在activity中findview出来

<com.facebook.react.ReactRootView
    android:id="@+id/test_js2"
    ....
/>
public class MyRNActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler 

    private ReactRootView mReactRootView,mReactRootView2;

    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_rn);

        mReactRootView = findViewById(R.id.test_js);
        mReactInstanceManager = ReactInstanceManager.builder()

                .setApplication(getApplication())

                .setCurrentActivity(this)//可以不需要此代码

                .setBundleAssetName("index.android.bundle")

                .setJSMainModulePath("index.android")//xxx.js
                .addPackage(new MainReactPackage())

                .setUseDeveloperSupport(true)

                .setInitialLifecycleState(LifecycleState.RESUMED)

                .build();

        // 注意这里的MyReactNativeApp必须对应“index.android.js”中的
        // “AppRegistry.registerComponent()”的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "MyRNActivity", null);

    

    @Override
    public void invokeDefaultOnBackPressed() 
        if(mReactInstanceManager!=null)
            mReactInstanceManager.onBackPressed();
        else
            super.onBackPressed();
        
    
    @Override
    protected void onResume() 
        super.onResume();
        if(mReactInstanceManager!=null)
            mReactInstanceManager.onHostResume(this,this);
        

    


    @Override
    protected void onPause() 
        super.onPause();

        if(mReactInstanceManager!=null)
            mReactInstanceManager.onHostPause(this);
        
    


    @Override
    protected void onDestroy() 
        super.onDestroy();

        if(mReactInstanceManager!=null)
            mReactInstanceManager.onHostDestroy(this);
        
    

九、Application继承ReactApplication

public class MyApp extends Application implements ReactApplication 

    private ReactNativeHost mReactNativeHost = new ReactNativeHost(this) 

        @Override
        public boolean getUseDeveloperSupport() 
            return true;
        

        @Override
        protected String getJSMainModuleName() 
            return "index.android";
        

        @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,false);
        

十、生成.bundle和.map文件

在app/main下创建assets文件夹,然后Android Studio Terminal在执行。0.49之后的版本index.android.js用index.js

$ react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.b
undle --assets-dest app/src/main/res/
>npm start

十一、一些坑

1.RN页面首次加载时,会白屏一下,可以采用 预加载 的方法

2.调试时请确保电脑和手机在同一WiFi环境下,不要使用WiFi共享类的软件,那可能导致APP红屏报404

3.红屏报错调用不到.so文件,app目录下的build.gradle中没有添加ndk abiFilters "armeabi-v7a", "x86"

swift5踩过的坑和奇怪的api笔记(代码片段)

踩过的坑和奇怪的API笔记UINavigationController导航栏设置导航栏颜色去掉导航栏下面的分割线设置导航栏字体和字体颜色UITabBarUITabBar和导航栏结合使用获取UITabBar的高度跳转界面隐藏UITabBar的方案UITableViewUITableViewCell里点击事件不生... 查看详情

编程中踩过的坑(代码片段)

...免的,分享出来希望大家不要再入坑,大家也可以分享出踩过的坑1、生成文件的坑编程过程中生成文件是一个很常见的需求,为了图方便我使用了反射去获取所有的字段,再一次写入文件中,我以为这是个很巧的方式,结果后... 查看详情

曾经面试踩过的坑,都在这里了~(代码片段)

...言  前段时间面试(包括阿里巴巴的电话面试),遇到过一些面试题,且面试中出现机率较高的提问/笔试,有些答的不是很好挂掉了,今天终于有时间整理出来分享给大家,希望对大家面试有所帮助,都能轻松拿offer。!>主要... 查看详情

技术分享|linux高并发踩过的坑及性能优化(代码片段)

...序开发多年,关于Linux系统下的高并发,小编自己踩过的坑,及如何解决踩过的坑下面列上几条,供大家参考,避免再次掉坑。Linux应用运行过程中出现Toomanyopenfiles问题分析和解决出现这句提示的原因是程序打... 查看详情

spring-data-redis使用过程中踩过的坑(代码片段)

spring-data-redis简介Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis,JRedis,andRJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,... 查看详情

那些年我们一起踩过的坑(代码片段)

总会有些坑,踩过了还想再踩。比较int大小时,如果简单的使用a-b>0来判断会很不安全。因为如果差值可能是int范围的两倍。如最大正数减最小负数。差值会溢出,截取低位。从而产生难以预见的错误。字节流和它的包装流,... 查看详情

appium踩过的坑(2021-12-31)(代码片段)

...个.下载完成之后长这样:神坑又来了打开appiuminspector输入一些必要参数然后就是死活连接不上…最终翻阅大量的官方文档之后得知最后连接就可以用啦…不用下载appium-inspector也可以也可以通过web的方式打开appium-inspectorweb-appium-ins... 查看详情

aardio_一些踩过的坑

1、关于延时的区别  a.sleep()        mainForm.button.oncommand=function(id,event)       mainForm.edit.print("start");       sleep(5000);       mainForm.edit.print("end");      运行效果:点击按钮,等待5秒,打印... 查看详情

elemenui-----tree树形结构踩过的坑(代码片段)

1、首先,必须保证数据结构是符合要求的,参照官方文档的数据结构:http://element-cn.eleme.io/#/zh-CN/component/tree2、做了本公司的用户管理:后台返回的树形菜单数据里既包含页面又包含操作权限(页面操作按钮),数据大致是这样... 查看详情

杂记6--一些c++踩过的坑(代码片段)

1、坑1ISOC++forbidstakingtheaddressofanunqualifiedorparenthesizednon-staticmemberfunctiontoformapointertomemberfunction.解决方法:在引用类中变量时,注意添加类名限制。2、坑2在c++的类中使用boost::bind,注意使用类实例:this... 查看详情

activity生命周期,学习笔记(踩过的坑)(代码片段)

关于Activity的生命周期问题,已经是很常见、很简单的问题了,但是偶尔还是会踩坑。这里,做个总结、笔记1、一个APP启动,启动后退到后台(home键),然后重新打开界面。这个过程是生命周期变化是... 查看详情

swift5踩过的坑和奇怪的api笔记(代码片段)

踩过的坑和奇怪的API笔记UINavigationController导航栏设置导航栏颜色去掉导航栏下面的分割线设置导航栏字体和字体颜色UITabBarUITabBar和导航栏结合使用获取UITabBar的高度跳转界面隐藏UITabBar的方案UITableViewUITableViewCell里点击事件不生... 查看详情

swift5踩过的坑和奇怪的api笔记(代码片段)

踩过的坑和奇怪的API笔记UINavigationController导航栏设置导航栏颜色去掉导航栏下面的分割线设置导航栏字体和字体颜色UITabBarUITabBar和导航栏结合使用获取UITabBar的高度跳转界面隐藏UITabBar的方案UITableViewUITableViewCell里点击事件不生... 查看详情

java中那些踩过的坑

仅以此随笔记录一些在java中踩过而且又重踩的坑 _(:з)∠)_1.RunnableInScheduledExecutorsService 当使用ScheduledExecutorService,Runnable内没有捕获的RuntimeException将会使Executor停止运行,并且异常不会被输出。    ScheduledExecutorServicesch... 查看详情

(ubuntucentos)nginx安装全部过程和踩过的坑(代码片段)

在Linux安装Nginx,看了许多视频与博客,讲的都不够细致,没有从头到尾完成整个过程,不适合初学者安装,这里我就来帮助大家完成Ubuntu和CentOS的Nginx安装一、Ubuntu安装安装Nginx之前先需要安装其3个依赖包1.安... 查看详情

一年开发做过的错事,踩过的坑

...sp; 这篇文章,作为自己开发一年的小总结。 因为一些问题造成了很多不必要的时间的浪费。 这篇文章比较适合,没有实际开发经验的人看。同样适合一年左右经验的人看。也欢迎有经验的可以给我提出宝贵的意见。... 查看详情

c#之winform可编辑table踩过的坑

界面图:完整代码:[数据库交互和一些工具类等忽略只看逻辑]usingSystem;usingSystem.Collections.Generic;usingSystem.Configuration;usingSystem.Data;usingSystem.Drawing;usingSystem.IO;usingSystem.Reflection;usingSystem.Text;usingSyst 查看详情

golang随机数生成踩过的坑记录一下(代码片段)

不废话了,直接上代码:packagemainimport("fmt""math/rand")funcmain()fmt.Println(rand.Intn(100))fmt.Println(rand.Intn(100)) 运行测试一下,$gorunrand.go8187OK,看似没问题,但再运行一次看看:$gorunrand.go8187输出的结果完全一样,查看官网上的例子:... 查看详情