2018-01-08 15:02:33 github_33905879 阅读数 243

Reactnative嵌套Android再嵌套ReactNative项目总结

转载请注明出处,阳仔在此谢谢啦!如有不妥多指教!
**
示例图:RN开发的理财app–>点击‘我要借款’—>跳转到RN开发的借款app—>点击返回按钮返回到理财app
这里写图片描述
需求:

**

  • 1.基于Reactnative开发一个Android项目;

  • 2.基于Android项目,app中部分功能使用Reactnative开发;

  • 3.Reactnative项目嵌套之前已经开发完成的Android项目;

  • 4.Reactnative项目嵌套之前已经开发完成的Reactnative项目。
    **

    其实这几种需求都是大同小异,只是对Reactnative结合Android原生开发有一定的了解之后的一种混搭运用。所以我只介绍最后一种最复杂的RN嵌套RN开发。本文只是自己在开发完后的总结,做笔记用,希望能对需要的人有所帮助。本人采用RN 0.44版本

一、项目结构分析(只介绍需要用到的东西,有不准确的地方希望可以理解。)

这里写图片描述
这张图是我的Reactnative项目的结构图,其中有些文可能你们自己自动创建的项目不包括,可以不用理会,只需要我划红线的文件有即可。
1.android:每个RN(Reactnative)项目的生成都会自动创建一个Android项目和iOS项目,这个文件夹下就是一个相当于Android Studio创建的Android项目。

2.app:这个文件夹是所有RN代码写出来的此项目的代码文件。

3.node_modules:RN开发所有依赖的源码所在。

4.index.android.js:入口文件,用于指向路由文件,启动此项目首先会运行这里面的代码。相当于生活中进屋子的门,想进去必须走这个门。

5.package.json:RN项目的配置文件,里面记录了,此RN项目的版本号,所依赖的第三方包等信息。

有开发经验的人应该已经理解了这些结构的含义了,不做过多解释。
这里写图片描述
此图是android文件夹下的Android结构,这个结构是已经是嵌套了RN项目后的结构。
1.assets:每个Android项目下都会有个assets目录,没有的自己在相应位置创建一下。里面放的四个文件index.android.bundle对应主项目的你开发完的代码文件,index.andorid2.bundle对应子RN项目的代码文件,打包的时候,apk会把这几个存有RN代码的文件一起打包。

2.AndroidManifest:android的配置清单文件,里面配置了Android的页面和第三方key等信息

3.build.gradle:android studio自动生成的文件,
android/app下的配置文件。app结合RN开发的时候里面需要配置一些信息

4.node_modules:同上

5.wallet:子RN项目的开发好的代码,同主项目的app文件夹。这个名字自己随便取名。我是直接把app文件夹改个名拷过来的

6.build.gradle:andorid项目下的配置文件

7.gradle.properties:也是配置文件,不细说了

8.index.android2.js:子RN项目的入口文件,作用同上

9.package.json:同上,这里是子RN项目的配置文件

10.settings.gradle:Android项目配置文件。

11.update.jaon:热更新文件。

12.local.properties:android配置文件,忘了划红线了。

二、原理

其实原理很简单,实现RN项目嵌套RN项目就是一个多层级调用问题

拆分成:
**

  • 1.Reactnative-Android项目
  • 2.Android-Reactnative项目(Android项目部分功能用RN开发)
  • 3.RN-android-RN:把前两步关联起来
    **

三、开始嵌套步骤

  • 1.备份,把你所有要开始操作的源码项目等做备份,以免嵌套出错无法还原项目,丢失源码。
  • 2.设计目录结构,设计一个好的目录结构,便于以后更新维护,迭代版本,避免二次开发等。
  • **3.排查避免两个RN项目中图片、布局文件等资源的名字
  • **4.把主RN项目中的android项目改成符合RN项目的结构,此流程可参考官方教程https://reactnative.cn/docs/0.44/integration-with-existing-apps.html#content

我自己是把子项目中的文件自己拷贝到Android项目中的,主要是package.json、update.json、node_modules、入口文件index.android2.js、子项目RN编写的代码。

开始:
(1)更改android/app/build.gradle:
这里写图片描述

这里写图片描述
app下的build.gradle下有个依赖node_modules的路径,改成android目录下的node_modules路径,这个时候相当于主RN项目的源码依赖也是这个node_modules了,如果忘了改这个路径会出现重复引用的报错。
Android SDK必须是6.0级别的这里写图片描述
dependencies下要把你两个RN项目依赖的第三方包也要都一起添加。
(2)更改Android项目的build.gradle.下面是我的android/build.gradle中的代码:这里写图片描述

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/node_modules/react-native/android"
        }
    }
}

(3)更改考入到android下的入口文件这里写图片描述
这里写图片描述
更改名字和路径到对应正确的路径和名字。
(4)子RN项目嵌入Android
这里写图片描述
新建一个Activity继承和实现图中类。
在onCreate()方法中添加必要的和自己子RN项目依赖的第三方包,这里的过程可以参考刚才上面给出的官网或者其他帖子(可以参考这个http://blog.csdn.net/win816723459/article/details/54317038)
(5)实现主RN项目调用嵌入到Android项目中的子RN项目
参考官网地址https://reactnative.cn/docs/0.44/native-modules-android.html#content实际就是官网教程里这个模块:
这里写图片描述
结合使用一下就可以了。
(6)生成index.android2.bundle到assets.
运行命令(里面部分文件名和路径自己根据自己实际情况去修改):

react-native bundle --platform android --dev false --entry-file index.android2.js  --bundle-output app/src/main/assets/index.android2.bundle  --assets-dest app/src/main/res/

最后会生成这样,分别是主RN和子RN项目的代码文件
这里写图片描述
最后编译没问题后打包测试,不打包是不能测试的。
###四、总结

其实就是对RN项目结构的一种灵活运用,我写的可能逻辑性不是很强,只是我的一种实现思路,具体可能会遇到很多问题,我当时自己花了很长时间去摸索出来。自己可以按照这个思路去试验一下。有问题可以联系我,咱们互相交流:QQ:3217609929 邮箱:lvyangdown@foxmail.com

2017-02-23 16:29:20 qq_32014215 阅读数 928

参考官方文档->react native 文档
本文使用开发环境 Android studio
注意最新的React Native支持的最新的SDK为16(android4.1)
npm环境,小伙伴们自己安装 nodeJS自己安装,可以参考官方文档安装环境.


创建Android项目(已有项目跳过)


  1. 打开Android studio

    14752189589833.jpg
  2. 输入项目名称,选择项目目录,点击next

    14752190447690.jpg


    14752191238908.jpg


    14752192158859.jpg


    14752193112367.jpg

至此项目创建完成(需要注意的是最新的React Native支持最新SDK版本为16 android4.1)

React Native集成到上面我们创建的ReactNativeAPPDemo中

参考Facebook react native文档

  1. 进入项目根目录,添加JS到项目中-点击Android studio中的Terminal(如下图)

    14752200412681.jpg

分别执行一下语句

  npm init
  npm install --save react react-native
  curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig

init 主要根据提醒生成package.json文件
install --save react react-native 安装React 和React Native
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 下载.flowconfig文件
参考图片


14752207192510.jpg

查看项目中有node_modules,说明react和react native 安装完成


14752214758622.jpg

在项目根目录添加.flowconfig

参考下图


14752216108448.jpg

也可以手动创建在浏览器打开https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig网址复制内容创建文件


14752217925862.jpg

ReactNativeAppDemo配置相关内容

  1. 添加"start": "node node_modules/react-native/local-cli/cli.js start" 到package.json 文件下 scripts标签 修改前

    14752220951994.jpg

    修改后

    14752221462812.jpg
  1. 添加index.android.js文件到项目中


    14752222197635.jpg
     'use strict';
     import React from 'react';
     import {
       AppRegistry,
       StyleSheet,
       Text,
       View
     } from 'react-native';
     class HelloWorld 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,
       },
     });
     AppRegistry.registerComponent('HelloWorld', () => HelloWorld);

    至此React native配置基本完成

  2. App build.gradle配置
    dependencies {
     ...
     compile "com.facebook.react:react-native:+" // From node_modules.
    }

    这里注意不要使用maven中的,因为我们使用的是我们本地node_modules中的,注意最新版本中支持的是23,appcompat-v7:23.0.1,暂时没有试24的api


    14752229775637.jpg
  1. 整个工程build.gradle配置
    >
    allprojects {
     repositories {
         ...
         maven {
             // All of React Native (JS, Android binaries) is installed from npm
             url "$rootDir/node_modules/react-native/android"
         }
     }
     ...
    }

14752256546683.jpg
  1. 添加<uses-permission android:name="android.permission.INTERNET" />AndroidManifest.xml:
  2. 确定External Libraries

    14752240537114.jpg


    14752241070972.jpg

确定是下是最新的,例如确定是0.34.1而不是0.20.1,如果出现请检查

  maven {
            `url "$rootDir/../node_modules/react-native/android"`//地址是否正确
        } 
 修改url "$rootDir*/..*/node_modules/react-native/android"为url "$rootDir/node_modules/react-native/android"

添加native code

官方给出的


14752232872479.jpg

到时最新版本中提供了更加简单的方式,没错就是继承。


14752258065933.jpg

在这里我们也需要自定义一个Application否则 运行时会报错,不信的小伙伴可以试一试


14752259787709.jpg

14752260351714.jpg

到此为止,ReactNative 集成到已有项目中完成!!!迫不及待的运行试试吧!!


14752261248709.jpg

在Terminal中运行 npm start,看到下图表示启动成功


14752261852021.jpg

运行以后发现如下错误


14752468221176.jpg

react-native报错:Could not get BatchedBridge, make sure your bundle is packaged correctly
莫紧张,这是因为bundle没有打包好。找不到编译打包后的js文件。其实就是android studio默认的寻找js文件地址和react-native自己的工具编译所使用的地址不同。

解决方法
方法一

进入项目,在android/app/src/main下新建assets目录。执行以下命令

$> react-native start > /dev/null 2>&1 &  
$> curl "http://localhost:8081/index.android.bundle?platform=android" -o
> "app/src/main/assets/index.android.bundle"

在项目根目录下执行

<!--$> (cd android/ && ./gradlew assembleDebug)-->
$> (cd 项目名称/ && ./gradlew assembleDebug)

把创建的apk安装到android设备

方法二

进入项目,在android/app/src/main下新建assets目录
启动服务器

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

在assets文件夹下会生成index.android.bundle文件,把创建的apk文件安装到android设备

方法三

进入项目,在android/app/src/main下新建assets目录
在package.json中配置下面代码

"scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "bundle-android": "react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --sourcemap-output app/src/main/assets/index.android.map --assets-dest android/app/src/main/res/"
  },

个人推荐使用方法三,方法三解决不了推荐方法二 手动执行
修改刚刚的package.json文件


14752486039953.jpg

如果真机(模拟器)需要执行

adb reverse tcp:8081 tcp:8081

一定要确定连接网络哦!!


14752520319630.jpg

14752520729313.jpg

开心的进行开发吧!

其他可能遇到的问题

ReactNative兼容64位Android手机

libgnustl_shared.so" is 32-bit instead of 64-bit类似错误

解决方法
  1. 在项目的根目录的 gradle.properties 里面添加一行代码
    android.useDeprecatedNdk=true.
  2. 在 build.gradle 文件里添加以下代码

    android {
    ...
    defaultConfig {
       ...
       ndk {
           abiFilters "armeabi-v7a", "x86"
       }
    
       packagingOptions {
           exclude "lib/arm64-v8a/librealm-jni.so"
       }
    }
    }
  3. Genymotion模拟器运行显示没有连接到developement server如下图

Paste_Image.png
  1. 先检查是否连接到网络
  2. 点击模拟器中Menu菜单弹出下面图片,点击Dev Settings

    Paste_Image.png
  3. 点击Debugging 下面的Debug Server host & port for device填写地址和端口

    Paste_Image.png


    Paste_Image.png


我的项目中依然可以看到,是不是有的小伙伴gradle文件配置的问题,仔细检查下,确实有问题的小伙伴,请加QQ私聊


Paste_Image.png
2018-06-01 11:00:21 public_calss 阅读数 928

如何简单的搭建一个ReactNative APP(Android和IOS通用)

一、下载一个webstorm工具

webstorm 2017 激活破解:https://blog.csdn.net/public_calss/article/details/78599308

二、搭建ReactNative开发环境

按照ReactNative中文官网步骤搭建: https://reactnative.cn/docs/0.51/getting-started.html
三、用webstorm新建一个React Native 项目
File Project ... — React Native — 点击Create就OK了 
这是最简单最快的了,所有相关的环境都会给你搭建好了,直接上手开发就好;
如果玩不来请参考 : 号称史上最详细android搭建 ReactNative项目( https://blog.csdn.net/cuoban/article/details/53764919),反正我按他的流程是在没搞好,所以自己又去摸索了一套适合自己的,我的是把Android、ReactNative(按中文官网步骤即可)环境安装好了后这样操作的,仅供参考,欢迎交流,共同学习。

2016-12-20 16:37:45 cuoban 阅读数 769

http://www.jianshu.com/p/22aa14664cf9?open_source=weibo_search

http://www.jianshu.com/p/22aa14664cf9?open_source=weibo_search
http://www.jianshu.com/p/22aa14664cf9?open_source=weibo_search


史上最详细的Android原生APP中添加ReactNative 进行混合开发教程

字数1568 阅读3041 评论28 

背景

React Native出来已经一段时间了,相对来说也算稳定了,在很多的企业中都实际使用他们,混合开发已经是未来的一种趋势,混合开发中使用的技术很多,不外乎HTML5、JS框架通过一定的技术和原始交互,目前主流混合开发React Native、Cordova、APICloud、MUI、AppCan、Sencha Touch、jQuery Mobile等等(其他的小伙伴们自己收集),目前网上写教程的人很多,但是React Native更新速度很快,根据他们的教程,中间会遇到各种问题,今天我和大家一起踩踩各种坑,让小伙伴们快速集成到自己的APP中。后续持续更新,反馈发邮件411437734@qq.com共同探讨。

集成步骤

参考官方文档->react native 文档
本文使用开发环境 Android studio
注意最新的React Native支持的最新的SDK为16(android4.1)
npm环境,小伙伴们自己安装 nodeJS自己安装,可以参考官方文档安装环境,有问题可以发411437734@qq.com沟通

创建Android项目(已有项目跳过)

  1. 打开Android studio

    14752189589833.jpg
  2. 输入项目名称,选择项目目录,点击next

    14752190447690.jpg


    14752191238908.jpg


    14752192158859.jpg


    14752193112367.jpg

至此项目创建完成(需要注意的是最新的React Native支持最新SDK版本为16 android4.1)

React Native集成到上面我们创建的ReactNativeAPPDemo中

参考Facebook react native文档

  1. 进入项目根目录,添加JS到项目中-点击Android studio中的Terminal(如下图)

    14752200412681.jpg

分别执行一下语句

  npm init
  npm install --save react react-native
  curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig

init 主要根据提醒生成package.json文件
install --save react react-native 安装React 和React Native
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 下载.flowconfig文件
参考图片


14752207192510.jpg

查看项目中有node_modules,说明react和react native 安装完成


14752214758622.jpg

在项目根目录添加.flowconfig

参考下图


14752216108448.jpg

也可以手动创建在浏览器打开https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig网址复制内容创建文件


14752217925862.jpg

ReactNativeAppDemo配置相关内容

  1. 添加"start": "node node_modules/react-native/local-cli/cli.js start" 到package.json文件下 scripts标签 修改前

    14752220951994.jpg

    修改后

    14752221462812.jpg
  1. 添加index.android.js文件到项目中


    14752222197635.jpg
     'use strict';
     import React from 'react';
     import {
       AppRegistry,
       StyleSheet,
       Text,
       View
     } from 'react-native';
     class HelloWorld 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,
       },
     });
     AppRegistry.registerComponent('HelloWorld', () => HelloWorld);

    至此React native配置基本完成

  2. App build.gradle配置
    dependencies {
     ...
     compile "com.facebook.react:react-native:+" // From node_modules.
    }

    这里注意不要使用maven中的,因为我们使用的是我们本地node_modules中的,注意最新版本中支持的是23,appcompat-v7:23.0.1,暂时没有试24的api


    14752229775637.jpg
  1. 整个工程build.gradle配置
    >
    allprojects {
     repositories {
         ...
         maven {
             // All of React Native (JS, Android binaries) is installed from npm
             url "$rootDir/node_modules/react-native/android"
         }
     }
     ...
    }

14752256546683.jpg
  1. 添加<uses-permission android:name="android.permission.INTERNET" />AndroidManifest.xml:
  2. 确定External Libraries

    14752240537114.jpg


    14752241070972.jpg

确定是下是最新的,例如确定是0.34.1而不是0.20.1,如果出现请检查

  maven {
            `url "$rootDir/../node_modules/react-native/android"`//地址是否正确
        } 
 修改url "$rootDir*/..*/node_modules/react-native/android"为url "$rootDir/node_modules/react-native/android"

添加native code

官方给出的


14752232872479.jpg

到时最新版本中提供了更加简单的方式,没错就是继承。


14752258065933.jpg

在这里我们也需要自定义一个Application否则 运行时会报错,不信的小伙伴可以试一试


14752259787709.jpg

14752260351714.jpg

到此为止,ReactNative 集成到已有项目中完成!!!迫不及待的运行试试吧!!


14752261248709.jpg

在Terminal中运行 npm start,看到下图表示启动成功


14752261852021.jpg

运行以后发现如下错误


14752468221176.jpg

react-native报错:Could not get BatchedBridge, make sure your bundle is packaged correctly
莫紧张,这是因为bundle没有打包好。找不到编译打包后的js文件。其实就是android studio默认的寻找js文件地址和react-native自己的工具编译所使用的地址不同。

解决方法
方法一

进入项目,在android/app/src/main下新建assets目录。执行以下命令

$> react-native start > /dev/null 2>&1 &  
$> curl "http://localhost:8081/index.android.bundle?platform=android" -o
> "app/src/main/assets/index.android.bundle"

在项目根目录下执行

<!--$> (cd android/ && ./gradlew assembleDebug)-->
$> (cd 项目名称/ && ./gradlew assembleDebug)

把创建的apk安装到android设备

方法二

进入项目,在android/app/src/main下新建assets目录
启动服务器

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

在assets文件夹下会生成index.android.bundle文件,把创建的apk文件安装到android设备

方法三

进入项目,在android/app/src/main下新建assets目录
在package.json中配置下面代码

"scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "bundle-android": "react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --sourcemap-output app/src/main/assets/index.android.map --assets-dest android/app/src/main/res/"
  },

个人推荐使用方法三,方法三解决不了推荐方法二 手动执行
修改刚刚的package.json文件


14752486039953.jpg

如果真机(模拟器)需要执行

adb reverse tcp:8081 tcp:8081

一定要确定连接网络哦!!


14752520319630.jpg

14752520729313.jpg

开心的进行开发吧!

其他可能遇到的问题

ReactNative兼容64位Android手机

libgnustl_shared.so" is 32-bit instead of 64-bit类似错误

解决方法
  1. 在项目的根目录的 gradle.properties 里面添加一行代码
    android.useDeprecatedNdk=true.
  2. 在 build.gradle 文件里添加以下代码

    android {
    ...
    defaultConfig {
       ...
       ndk {
           abiFilters "armeabi-v7a", "x86"
       }
    
       packagingOptions {
           exclude "lib/arm64-v8a/librealm-jni.so"
       }
    }
    }

    最后感谢

    http://majing.io/questions/589
    http://www.cnblogs.com/tony-yang-flutter/p/5864578.html
    https://blog.yourtion.com/update-react-native-029-bug.html
    http://stackoverflow.com/questions/38870710/error-could-not-get-batchedbridge-make-sure-your-bundle-is-packaged-properly/38874952
    http://blog.csdn.net/b992379702b/article/details/52234479
    Genymotion模拟器运行显示没有连接到developement server如下图

Paste_Image.png
  1. 先检查是否连接到网络
  2. 点击模拟器中Menu菜单弹出下面图片,点击Dev Settings

    Paste_Image.png
  3. 点击Debugging 下面的Debug Server host & port for device填写地址和端口

    Paste_Image.png


    Paste_Image.png

上文中使用到的项目ReactNativeAPPDemo链接: https://pan.baidu.com/s/1i4GkeKt 密码: vwym

最近小伙伴反馈0.39.0上面没有ReactApplication接口,请看我的截图有问题QQ联系我共同探讨

我的项目中依然可以看到,是不是有的小伙伴gradle文件配置的问题,仔细检查下,确实有问题的小伙伴,请加QQ私聊


Paste_Image.png


2016-06-20 16:23:37 u011916937 阅读数 2156

前言

公司现有app中部分模块使用reactnative开发,之前使用的都是webview来加载H5页面,在实施的过程中,reactnative良好的兼容性,极佳的加载、动画性能,提升了我们的开发、测试效率,提升了用户体验。

但是,在android中,当点击某个rn模块的入口按钮,弹出rn的activity到rn的页面展现出来的过程中,会有很明显的白屏现象,不同的机型不同(cpu好的白屏时间短),大概1s到2s的时间。这是因为每次加载reactAcivity都是会去重新加载js资源包,初始化,导致加载时间过长。

分析问题

一般优化速度问题,首先就是要找到时间分布,然后根据二八原则,先优化耗时最长的部分。android集成rn都会继承官方提供的ReactActivity。

public class MainActivity extends ReactActivity {

然后只在自己的activity中覆盖一些配置项。

在官方的ReactActivity中的onCreate方法中

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {
      // Get permission to show redbox in dev builds.
      if (!Settings.canDrawOverlays(this)) {
        Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
        startActivity(serviceIntent);
        FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
        Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
      }
    }

    mReactInstanceManager = createReactInstanceManager();
    ReactRootView mReactRootView = createRootView();
    mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());
    setContentView(mReactRootView);
  }

最慢的就是这三行代码,占了90%以上的时间。

mReactInstanceManager = createReactInstanceManager();
    ReactRootView mReactRootView = createRootView();
    mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());

第一行是创建React管理的实例把jsbundle文件读入到内存中。

第二行是创建React页面。

第三行是初始化React页面。

解决方案

优化思路:内存换取时间,在app启动时候,就将mReactRootView初始化出来,并缓存起来,在用的时候直接setContentView(mReactRootView),达到秒开,但是由于每次页面都是继承ReactActivity,页面不同,每次都要重新初始化新的页面,我们把ReactInstanceManager写成单例的模式,创建一次,加载jsbundle文件缓存在内存中,不需要每次都去加载资源,减少加载时间。
创建RNCacheManager:
package com.haier.hairy.react;

import android.app.Activity;

import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.framework.util.Preferences;
import com.microsoft.codepush.react.CodePush;

import java.util.Arrays;

/**
 * React管理缓存类
 * Created by fww
 * date 16/6/20.
 */
public class RNCacheManager {
    private static ReactInstanceManager mManager = null;
    private static RNCacheManager mInstance;
    private static CodePush codePush;


    public static RNCacheManager getInstance(Activity activity){
        if(mInstance==null){
            mInstance = new RNCacheManager();
            codePush = new CodePush(Preferences.DEBUG?/*"1RMMWRaTi1WhB8z1CEjH3B5aRztnEJTjrzq6l"*/"iTJagF-2Ox8EJAp6kfQ5JO7hHoM8EJTjrzq6l":"GYGm87k_sh4ObCJwrI5qNH-i_9f9EJTjrzq6l", activity, Preferences.DEBUG);
            mManager = createReactInstanceManager(activity);
        }

        return mInstance;
    }
    public ReactInstanceManager getManager(Activity activity){
        if(mManager==null){
            mManager = createReactInstanceManager(activity);
        }

        return mManager;
    }
    private static ReactInstanceManager createReactInstanceManager(Activity act) {

        ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
                .setApplication(act.getApplication())
                .setJSMainModuleName("")
                .setUseDeveloperSupport(Preferences.DEBUG)
                .setInitialLifecycleState(LifecycleState.BEFORE_RESUME);

        for (ReactPackage reactPackage : Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new SpringBoardPackage(),
                codePush.getReactPackage()
        )) {
            builder.addPackage(reactPackage);
        }

        String jsBundleFile = codePush.getBundleUrl("main.jsbundle");;

        if (jsBundleFile != null) {
            builder.setJSBundleFile(jsBundleFile);
        } else {
            builder.setBundleAssetName("main.jsbundle");
        }
        return builder.build();
    }
}
重写ReactActivity:

将官方的ReactActivity粘出来,重写2个方法,onCreate和onDestroy,其余代码不动。

onCreate方法中使用缓存ReactInstanceManager管理器来获得ReactInstanceManager对象,而不是重新创建。

这里曾尝试继承ReactActivity,而不是重写这个类,但是子类覆盖onCreate方法时候,必须要调用super.onCreate,否则编译会报错,但是super.onCreate方法会重新创建rootview,所以实在是绕不过去了。

这里的CodePush是微软的CodePush包,用于更新资源包的,可以不加注释掉,感兴趣的同学可以了解下。

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {
            // Get permission to show redbox in dev builds.
            if (!Settings.canDrawOverlays(this)) {
                Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                startActivity(serviceIntent);
                FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
                Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
            }
        }
        RNCacheManager rnCacheManager = RNCacheManager.getInstance(this);
        mReactInstanceManager = rnCacheManager.getManager(this);
        ReactRootView mReactRootView = createRootView();
        mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());
        setContentView(mReactRootView);
    }

onDestroy方法中,不能再调用原有的mReactInstanceManager.destroy()方法了,否则rn初始化出来的对象会被销毁,下次就用不了了。可以把它注释掉,试了不会报错,最好的办法就是做个标记,最好一个的时候destroy()。

      protected void onDestroy() {
            super.onDestroy();
    
            if (mReactInstanceManager != null) {
    //            mReactInstanceManager.onDestroy();
            }
        }

亲测,第一次加载时间长点,以后的加载使用 缓存都是秒开的。



没有更多推荐了,返回首页