在现有android项目上集成RN(二)

现在很多公司因为发展需要集成RN,但是要在现有的android项目上如何去集成呢?That's a Question,这篇文章主要就是讨论下如何集成,大神绕步

要想集成RN,首先我们需要引入RN的库
1525253415655.jpg

ok,so easy,然而编译后很多人就悲剧了,你可能会报下面这个错误
1525253681649.jpg

很慌有没有,没事仔细看看错误日志,它说我现在是用的是react-native 0.20.1的版本,what?现在RN版本都0.51+了,作为追求新版本的我们怎么能用这么low的版本,那么怎么解决呢?

首先,在你的安卓项目的根目录下npm init,如下:

yhd@yihaodiandeMacBook-Pro RnApplication $ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install ` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (rnapplication) rntest
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /Users/yhd/Desktop/RnApplication/package.json:
{
  "name": "rntest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Is this ok? (yes) yes

操作完后在你的安卓项目根目录下会出现一个package.json文件
1525254162270.jpg

修改package.json如下

{
  "name": "rntest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "author": "",
  "license": "ISC"
}

紧接着我们安装react和react-native

yhd@yihaodiandeMacBook-Pro RnApplication $ npm install [email protected]
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

+ [email protected]
added 18 packages from 73 contributors in 4.234s

┌────────────────────────────────────────────────────────┐
│                npm update check failed                 │
│          Try running with sudo or get access           │
│          to the local update config store via          │
│ sudo chown -R $USER:$(id -gn $USER) /Users/yhd/.config │
└────────────────────────────────────────────────────────┘
yhd@yihaodiandeMacBook-Pro RnApplication $ npm install [email protected]
npm WARN deprecated [email protected]: connect 2.x series is deprecated

> [email protected] install /Users/yhd/Desktop/RnApplication/node_modules/fsevents
> node install

[fsevents] Success: "/Users/yhd/Desktop/RnApplication/node_modules/fsevents/lib/binding/Release/node-v57-darwin-x64/fse.node" already installed
Pass --update-binary to reinstall or --build-from-source to recompile
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

+ [email protected]
added 777 packages from 324 contributors in 58.036s

这里我们react安装的是16.0.0,react-native安装的是0.51.1

安装完毕后我们发现android项目根目录下多了一个node_modules文件夹

最后在build.gradle里添加如下代码
1525255161467.jpg

ok,编译运行,依然报错,心拔凉,看下日志
1525255292550.jpg

发现版本是改过来了,报错原因是minSdkVersion太低,ok改成16,编译通过,美滋滋

接下来就可以写RN页面了

写一个Activity继承自ReactActivity
public class MainActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {
        return "YRNTest";
    }
}
自定义一个Application
public class MyApplication extends Application implements ReactApplication {
    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return true;
        }

       @Override
        protected String getJSMainModuleName() {
            return "index";
        }

        @Override
        protected List getPackages() {
            return Arrays.asList(
                    new MainReactPackage()
            );
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }
}
getUseDeveloperSupport方法返回true表示debug模式

ok,设置完毕,注意这里的getJSMainModuleName返回的是index,那么我们的android项目根目录下的js文件得取名为index.js,默认getJSMainModuleName返回的是index.android,那么我们取名为index.android.js,以此类推。最后不要忘记注册自定义的Application
1525256303196.jpg

启动RN服务,在android项目根目录下运行如下npm start

yhd@yihaodiandeMacBook-Pro RnApplication $ npm start

> [email protected] start /Users/yhd/Desktop/RnApplication
> node node_modules/react-native/local-cli/cli.js start

Scanning folders for symlinks in /Users/yhd/Desktop/RnApplication/node_modules (10ms)
 ┌────────────────────────────────────────────────────────────────────────────┐ 
 │  Running Metro Bundler on port 8081.                                       │ 
 │                                                                            │ 
 │  Keep Metro Bundler running while developing on any JS projects. Feel      │ 
 │  free to close this tab and run your own Metro Bundler  instance if you    │ 
 │  prefer.                                                                   │ 
 │                                                                            │ 
 │  https://github.com/facebook/react-native                                  │ 
 │                                                                            │ 
 └────────────────────────────────────────────────────────────────────────────┘ 
Looking for JS files in
   /Users/yhd/Desktop/RnApplication 


Metro Bundler ready.

Loading dependency graph, done.

现在我们来重新运行项目,nice,崩溃了
我们看一下崩溃日志

FATAL EXCEPTION: Thread-1867
                                                                           Process: com.zsh.yhd.rnapplication, PID: 22576
                                                                           java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.zsh.yhd.rnapplication/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit
                                                                               at java.lang.Runtime.load(Runtime.java:332)
                                                                               at java.lang.System.load(System.java:1069)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:71)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
                                                                               at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:65)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
                                                                               at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:65)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
                                                                               at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:65)
                                                                               at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
                                                                               at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
                                                                               at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:247)
                                                                               at com.facebook.react.bridge.ReactBridge.staticInit(ReactBridge.java:20)
                                                                               at com.facebook.react.bridge.NativeMap.(NativeMap.java:21)
                                                                               at com.facebook.react.bridge.JSCJavaScriptExecutorFactory.create(JSCJavaScriptExecutorFactory.java:23)
                                                                               at com.facebook.react.ReactInstanceManager$4.run(ReactInstanceManager.java:928)
                                                                               at java.lang.Thread.run(Thread.java:818)

导致这个问题的原因是:React Native项目在64位Android手机上运行
解决方法就是取消掉所有的64位的.so文件,全部加载32位的就可以了,下面是步骤
1.在项目的根目录的 gradle.properties 里面添加一行代码 android.useDeprecatedNdk=true

2.在 build.gradle 文件里添加以下代码
1525316453690.jpg

再次编译运行,成功显示出js页面

最后,别忘记在AndroidManifest.xml里面添加权限,附上图片
1525316641484.jpg

ok,js代码也附上
1525317265146.jpg

你可能感兴趣的:(在现有android项目上集成RN(二))