记录一次 ReactNative + Android 混合开发

本篇博客仅作个人记录,如有错误大佬们欢迎提醒、评论、以及交流ReactNative技术。

我查看了许多博客,发现大多都写的比较简练,我就来结合自身的经验做个梳理和总结,帮助小白们加深一下对ReactNative+Android混合开发的理解。

这里说的混合开发与官网上说的【集成到现有原生应用】存在区别,一个是以原有的Android项目为基础,在此之上某一两个页面或业务流程用ReactNative。

而本博客要说的是在默认ReactNative项目的基础之上添加新的Android原生代码或者说原生页面。


相信大多数利用ReactNative开发的小伙伴们和我一样是前端出身,但是又对App感兴趣,所以入坑了ReactNative (说实话确实坑)。在此我会用一些前端的情况做类比,便于大家理解😄。

场景:ReactNative开发的App,无法完全满足业务需求,需要将第三方Android原生demo植入ReactNative项目中。


分析:从文件结构上看ReactNative项目在构建之初是一个单页面的App,利用了JavaScript构建的页面(实际上准确说并不是;RN是利用了桥接技术调用宿主平台的绘图API进行UI层的绘制,具体实现原理可以看官网的文档...这里先姑且这么说。这与uniapp等直接利用浏览器内核作为运行时的开发技术有着本质区别)其外在表现形式类似于前端的SPA模式,页面变化但不打开新的html页面。当用户进行页面跳转时,ReactNative其实是利用了 【React Navigation】 这个第三方库进行页面动画的绘制,从而达到了页面跳转的显示效果。但是这与传统原生开发时利用Intent进行Activity容器之间的跳转存在本质区别。(简单来说传统android开发一个Activity就是一个页面


思考:既然默认的ReactNative可以算是一个单页面应用,那我们能不能给它加上一些原生的Activity容器,再通过一些操作让它从默认的Activiy上跳转到新的Activity上呢🤔?类似于通过我这个SPA,在浏览器上打开一个新的标签页呢?

那就试试

第一步:我们要先看明白,怎么实现JavaScript层与原生层的通信。这里可以直接查看官方的文档,有这详细的说明【原生模块通信】。如果你是新手请仔细看文档一步一步来。 简单来说:就是我们需要一个自定义的package,一个自定义的module。将module添加到package中,再将package添加到MainApplication.java中。我们在module中定义一个利用@ReactMehod注解的方法,以提供JavaScript进行调用(注意引入对应的module,module的名称要写对),从而达到JavaScript调用Android方法的目的。

第二步:这里时候相信你己经可以通过JavaScript去调用你在Activity中写的Java/kotiln代码了😄。接下来就是利用Intent去跳转到另外一个新建的Activity上。这个方案可以在android的官方文档上找到。【启动另外一个activiy】

Android代码如下:(注意对应包的引入

import android.app.Activity;
import android.content.Intent;
import android.widget.Toast;


..................
/// 你的某个自定义的module类中


@ReactMethod
public void test(String name, String params) {
    try {
        Activity currentActivity = getCurrentActivity();
        if (null != currentActivity) {
            Class toActivity = Class.forName(name);
            if (null != toActivity) {
                Intent intent = new Intent(currentActivity, toActivity);
                intent.putExtra("params", params);
                currentActivity.startActivity(intent);
            } else {
                Toast.makeText(getReactApplicationContext(), "toActivity [" + name + "] is null", Toast.LENGTH_LONG)
                            .show();
            }
        }
    } catch (Exception e) {
        throw new JSApplicationIllegalArgumentException(
                "不能打开Activity : " + e.getMessage());
    }
}

JavaScript代码如下:

<Button title="JavaSecondActivity" onPress={() => {
                    DemoModule.test("com.rn_sample.JavaSecondActivity", null);
                }} />

这里的目标Activiy名称要与你本地项目的Activiy名称对应。rn_sample是我的ReactNative项目名称,JavaSecondActivity是我自定义的一个Activiy。

e030bfbc0406429696f8ce1ab9d33179.png

第三步 

创建一个自定义的Activity。如上图我创建的JavaSecondActivity。再在AndroidManifest.xml中注册该Activity。注意你的文件路径。填写位置应该与默认的activity平级,在<application>标签内部。

<activity android:name="com.rn_sample.JavaSecondActivity"></activity>

至此,菜都上齐了。

只需要你再重新编译跑一遍就行了。至此你点击这个button是它会帮你调用module中的方法,该原生方法又帮你跳转到你新的空白的Activity上了。搞定。

还有就是原生的Activiy是通过直接触发调用finish(),进行页面销毁的。表现形式就和页面后退一致。这与JavaScript中调用路由有所不同。


另外再补充一点:如果你和我一样需要面对Java与Kotlin混编的情况,记住添加插件否则AndroidStudio编译不通过。

代码如下:

a0bc2c4021b54a99a86a4b356139b2d0.png

6057a93df6c64bfebd07d1b0e7fb6b90.png

 在打包时,也注意一下是否要开启混淆。有些库混淆后导致无法找到对应的变量或方法导致运行崩溃。还找不到报错的具体行列。我就被坑了。

1c9f719493c041bcac8015ae5c9dcbf3.png

 总结:个人感觉虽然ReactNative帮助我们前端程序员进入到了移动端开发的领域,但还是需要一定的原生端的知识储备,不然在遇到问题时,也不知道问题的根本在哪里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值