ReactNative集成进Android项目
ReactNative已经发展了一段时间.现在最新版本是
version 0.55
虽然还没有稳定的v 1.0
版本,但是现在的功能已经可以承担起项目跨平台的开发任务. 丰富的第三方组件库提供了全面的功能解决方案的同时解决了大部分Android
和ios
平台兼容的问题. 这使得ReactNative
生态不断发展,更加完美.
现在,我们一起探索一下ReactNative & Android
混合开发.
首先,我们要将ReactNative
集成进一个现有的Android
项目
一. 环境搭建和Hello World RN项目的创建
这个主题网上有近乎完美的文档,这里不再赘述.以下是可以参考的文档.
- ReactNative中文网-搭建开发环境
- ReactNative官网-搭建开发环境
二. 项目合并
在做这一步之前,我们已经有了使用react-native init HelloWorld
产生的RN 项目 和一个已经存在的Android项目,现在我们的文件夹里两个项目像下图一样:
2.1 新建合并工程 RNAndroid合并文件
- 新建
RNAndroid
文件夹.并在里面新建一个android
文件夹. - 复制
AndroidRNDemo
文件夹下的所有文件复制到上面新建出来的android
文件夹中 -
HelloWorld
文件夹中的**App.js
,app.json
,index.js
,package.json
,ios
(文件夹), 复制到RNAndroid
文件夹里.
完成后的RNAndroid
文件夹是这样的:
至此,文件合并结束.
2.2 修改Android项目的build.gradle
文件
以下操作都在android
文件夹里面进行
使用AndroidStudio打开android文件夹,然后开始修改文件.
- 打开项目层级的
build.gradle
文件,在里面添加如下代码:
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
- 打开module层级的
build.gradle
文件
在里面添加依赖代码
//noinspection GradleCompatible
compile 'com.android.support:appcompat-v7:23.1.0'
compile "com.facebook.react:react-native:+" // From node_modules.
至此我们完成里android构建文件的修改
2.3 让android Application实现 ReactApplication
接口
这一步实现接口并实现一个getReactNativeHost()
方法.
在MainActivity.java
同级目录下新建'MyApplication.java'文件,完成后的代码如下:
package com.gomorrow.androidrndemo;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;
/**
* 作者: Panda8
* 日期: 2018/4/20 15:02.
*/
public class MyApplication extends Application implements ReactApplication{
ReactNativeHost mReactNativeHostnew = new
ReactNativeHost(this){
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHostnew;
}
}
设置应用使用MyApplication启动
2.4 MainActivity 继承ReactActivity
完成后的MainActivity
代码如下:
package com.gomorrow.androidrndemo;
import com.facebook.react.ReactActivity;
import javax.annotation.Nullable;
public class MainActivity extends ReactActivity {
@Nullable
@Override
protected String getMainComponentName() {
//这里返回index.js里面export的module name
return "HelloWorld";
}
}
2.5 同步下代码确定React-Native的版本是不是最新的0.55.3
2.6 添加so库的支持
在app/gradle 文件里添加如下代码
{
....
ndk {
abiFilters "armeabi-v7a", "x86", 'armeabi', 'arm64-v8a'
}
packagingOptions {
exclude '/lib/mips64/**'
exclude '/lib/arm64-v8a/**'
exclude '/lib/x86_64/**'
}
}
不添加运行时的报错信息如下:
2.7 配置adb端口
在终端中运行下面的语句
adb reverse tcp:8081 tcp:8081
2.8 添加开发者页面
在清单文件中添加一行
2.9 添加网络权限
在清单文件中添加一行
至此: 清单文件的所有内容如下
最后,终于可以Run一下了.这个时候会完全没有错误的启动AndroidAPP. 但是这个APP还不能真正的称得上是混合开发的APP. 混合开发意味着两种语言可以无缝通信. 接下来我们来进行ReactNative代码和Android原生java代码实现通信的部分.
三. Android和ReactNative的互相调用和通信.
两种语言通信,通常需要协议支持,而在ReactNative的开发中这个协议已经实现高内聚封装.我们需要操作的协议部分被浓缩成了两个类(对于Android的Java),一个对象(对于RN的JavaScript).
3.1 两个类.
ReactPackage
ReactContextBaseJavaModule
在js和java的通信中. ReactNative将协议封装成'package'和'module'两个部分.
其中module
负责定义可以在JavaScript层调用的方法,'package'负责将module
打包供ReactNative(js)层调用
3.2 module
package com.gomorrow.androidrndemo;
import android.content.Intent;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
/**
* 作者: Panda8
* 日期: 2018/4/20 15:02.
*/
public class JSBundleManager extends ReactContextBaseJavaModule {
public JSBundleManager(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "JSBundleManager";
}
/*
* 定义一个可以被js调用的方法使用注解@ReactMethod声明
*/
@ReactMethod
public void startNativeActivity() {
Intent intent = new Intent(getReactApplicationContext(),SplashActivity.class);
getCurrentActivity().startActivity(intent);
}
}
3.3 package
Package负责打包module
public class JSBundlePackage implements ReactPackage {
@Override
public List createNativeModules(ReactApplicationContext reactContext) {
List modules = new ArrayList<>();
modules.add(new JSBundleManager(reactContext));
return modules;
}
@Override
public List createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}