React-Native学习之嵌入Android原生项目

文章有点长,耐心看下去,希望能够帮助你
邮箱:[email protected]

关于React-Native(以下简称RN)的环境配置和搭建请参考官方教程http://reactnative.cn/
下面说一下如何创建一个混合项目和我在创建项目时碰到的一些问题
我就按照我自己操作的步骤一步步来

创建Android项目

  • 最低的SDK版本是16,RN官方是支持SDK23

关于项目的项目的配置

这是我的个人配置的
按照正常的步骤,我们开始初始化项目

用Terminal来实现,当然也可以用终端

rn配置

npm init

我们需要手动输入一些信息

有一些内容直接回车就是使用默认值,但是有一个位置需要数一下,main,就是入口,我是Android的所以创建的index.android.js(默认的就是index.js)
我们继续
我们开始执行npm install –save react react-native
note:在这个位置可能会比较慢,我们可以添加淘宝的镜像

npm config set registry https://registry.npm.taobao.org –global
npm config set disturl https://npm.taobao.org/dist –global
等待上面的运行结束
curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
运行结束之后我们会发现多了一个文件

关于为什么这样做,大家可以去百度一下,我就不再这里展开说了
上面的工作都做完的话就可以开始准备app上面的配置了
app配置
在project的级别的build.gradle->allprojects->repositories下添加

  maven {
            //添加react native依赖,url路径根据实际的来写,本文的如下:
            url "$rootDir/node_modules/react-native/android"
        }

在这里说明一下,Android一般常规引用的都是jcenter内的库,里面包含的最高就是0.20.1

所以我们需要更换到对应的maven库来添加对应版本的rn
接下来我们需要进行dependencies下的引用

compile "com.facebook.react:react-native:+"

如果在配置的时候碰到了下面这个问题,我们可以添加相关引用就好了,在module级别的bulid.gradle->android节点下添加依赖

configurations.all {
    resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}

到这里我们的配置基本上就都完成了

项目编辑

rn编写

还记的上面说的main对应的index.android.js的入口么?
现在我们在项目的根目录创建对应的文件了

创建完成之后我们随便写点内容吧

import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
class HelloWorldApp extends Component {
  render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);

就来个最经典的吧
这样我们rn这边的东西就写完了

Android编写

下面是官方给出的写法,所以我们在学基础的时候可以借鉴一下

public class MyActivity extends Activity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mRootView;
    private ReactInstanceManager mReactManager;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mRootView = new ReactRootView(this);
        mReactManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")//启动加载的文件,可以用于打包生成apk
                .setJSMainModuleName("index.android")//启动入口
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(true) //开发者模式的开关
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        //HelloWorldApp这个名字要和刚刚创建的rn项目名一样
        mRootView.startReactApplication(mReactManager, "HelloWorldApp", null);
        setContentView(mRootView);
    }
    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
    @Override
    protected void onPause() {
        super.onPause();
        if (mReactManager != null) {
            mReactManager.onHostPause(this);
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        if (mReactManager != null) {
            mReactManager.onHostResume(this, this);
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mReactManager != null) {
            mReactManager.onHostDestroy(this);
        }
    }
    @Override
    public void onBackPressed() {
        if (mReactManager != null) {
            mReactManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        //当我们点击菜单的时候打开发者菜单,一个弹窗(此处需要悬浮窗权限才能显示)
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactManager != null) {
            mReactManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }
}

下面有两个地方需要注意一下

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

我们声明相关权限,第二个是悬浮窗体权限,关于悬浮窗权限我们需要手动来设置,高于6.0的Android需要添加以下代码

if (Build.VERSION.SDK_INT >= 23) {
            if(!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                startActivity(intent);
            } 
        } 
 <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

我们需要将原声的devSetiingsActivity进行相关的声明
相关的已经编写完了,我们来开启模拟器运行一下

运行项目

我们用npm start或者react-native start来开启运行,我们来试一下

运行到了这里,我们运行项目,发现报错了
dlopen failed: “/data/data/com.mockuai.rndemo/lib-main/libgnustl_shared.so” is 32-bit instead of 64-bit
我们需要对项目进行相关配置,很明显这是一个so库对应不上的问题,我们需要将64位库进行屏蔽,然后全部使用32位库
配置module级别下的build.gradle如下

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

再来一遍

你会发现你已经看到了你想要的界面

关于一些其他问题,我们需要注意的一些
- 模拟器无法连接到服务,我们需要设置adb reverse tcp:8081 tcp:8081来设置一下端口
- 我们在打包apk的时候需要注意将setUseDeveloperSupport(true)改为false,我们需要在src-main创建assets目录,然后运行下面的命令生成静态的bundle文件

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/

猜你喜欢

转载自blog.csdn.net/xiangnicao/article/details/75038166