将本机放入Android上的React Native

在React Native中使用自定义本机组件是很平常的事情,因此迟早您可能不得不用本机语言编写一些功能并在您的应用程序中使用它。 让我向您展示一个简单的示例。

First prepare code in a separate application

我们从创建一个简单的本机应用程序开始。 在此示例中,当耳机插入或拔出时,我们的应用程序将显示用户信息。 它涉及多种本机交互:

  • 注册或取消注册侦听器时的应用程序生命周期交互通过意图发送和接收数据通过烤面包显示信息使用应用程序上下文

假设您熟悉创建本机Android应用程序的情况,下面的示例将非常简单。 我们的应用程序使用一种活动,其布局简单,以后将不再相关。 从将用于我们的活动的私有字段开始:

private Context mContext;

private final BroadcastReceiver mHeadsetPlugReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
            boolean plugged = (intent.getIntExtra("state", 0) == 1);
            String message = plugged ? "Headset plugged in" : "Headset plugged out";
            Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
        }
    }
};

只要我们可以调用,就不必总是记住对您的应用程序上下文的引用getApplicationContext活动中的方法。 现在保留它,因为稍后我们将对其进行修改。 广播接收器是一个抽象类,描述了通过Intent接收信息时的行为。

注册侦听器如下所示:

private void registerBroadcastReceiver() {
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_HEADSET_PLUG);
    registerReceiver(mHeadsetPlugReceiver, filter);
}

registerReceivermethod是Activity的方法,可以在Context类对象上调用。

在onCreate方法保存对应用程序上下文的引用并注册广播接收器:

mContext = this;
registerBroadcastReceiver();

最后,遵循简洁的编码原则,在使用Activity的应用程序关闭应用程序时注销接收器取消注册方法:

@Override
protected void onDestroy() {
    unregisterReceiver(mHeadsetPlugReceiver);
    super.onDestroy();
}

就是这样,这就是我们要进行的工作。 插入耳机时,该应用程序显示一条简单消息:

让我们在我们的RN项目中使用它!

/react-project/android

在您的React项目目录中,有一个安卓夹。 它的结构看起来像每个Android项目,您可以使用Android Studio打开它以方便导航。 源文件在/ app / src / main / java / {some} / {packages} /在这里,我们将添加我们的代码。 我们将必须以特定方式打包我们的功能。 校验Main应用.java首先归档。 它在延伸应用类和工具React应用接口。 看一眼getPackages方法:

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

用React Native编写的应用程序的构建方式与其他任何Android应用程序一样,但是React Native软件包是在运行时添加的,并在此处指定。 您可以编写任何本机代码并将其链接到此处,但必须将其添加为ReactPackage并初始化它getPackages方法。 将需要两个文件:包和模组。

首先创建一个实现com.facebook.react.ReactPackage接口。 它有两种方法,其基本实现如下所示:

public class MyHeadsetLibPackager implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new MyHeadsetLibModule(reactContext));

        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

最重要的部分是在createNativeModules方法:

modules.add(new MyHeadsetLibModule(reactContext));

MyHeadsetLibModule是我们命名第二班的方式。 它将包含我们库的所有功能。 有必要扩展com.facebook.react.bridge.ReactContextBaseJavaModule该类。


import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;

public class MyHeadsetLibModule extends ReactContextBaseJavaModule {

    public MyHeadsetLibModule(ReactApplicationContext reactContext) {

        super(reactContext);

        /*
            Our starting point.
        */

    }
}

编译项目的最后一件事是添加对/app/build.gradle

dependencies {
    ...
    compile "com.facebook.react:react-native:+"
    ...
}

Moving from activity

现在,我们可以像执行活动一样执行所有操作。 只需留意从活动至ReactContextBaseJavaModule。

第一: 谁有上下文? From now we cannot call activity's methods like registerReceiver就这样 我们也无法通过调用来访问应用程序的上下文getApplicationContext。 这就是为什么在模块的构造函数中ReactContext实例。 所有活动的方法都会从中调用。

第二: 生命周期方法在哪里? Right now nowhere. But just implement LifecycleEventListener在您的模块类中。 它是一个提供三种基本生命周期方法的接口:

  • void onHostResume()void onHostPause()void onHostDestroy()

所有生命周期功能都在这里实现。 然后在构造函数中注册监听器reactContext.addLifecycleEventListener(this)并做了。 我们的模块现在的行为就像活动。

使模块可见的最后一件事是覆盖getName方法。 它应该返回我们模块的名称,如下所示:

@Override
public String getName() {
    return "MyHeadsetLibModule";
}

遵循所有这些准则,从活动重写的模块的最终形式如下所示:


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Toast;

import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;

public class MyHeadsetLibModule extends ReactContextBaseJavaModule implements LifecycleEventListener {

    private ReactApplicationContext mContext;

    private final BroadcastReceiver mHeadsetPlugReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
                boolean plugged = (intent.getIntExtra("state", 0) == 1);
                String message = plugged ? "Headset plugged in" : "Headset plugged out";
                Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
            }
        }
    };

    public MyHeadsetLibModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
        registerBroadcastReceiver();
    }

    private void registerBroadcastReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_HEADSET_PLUG);
        mContext.registerReceiver(mHeadsetPlugReceiver, filter);
    }

    @Override
    public String getName() {
        return "MyHeadsetLibModule";
    }

    @Override
    public void onHostResume() {

    }

    @Override
    public void onHostPause() {

    }

    @Override
    public void onHostDestroy() {
        mContext.unregisterReceiver(mHeadsetPlugReceiver);
    }    
}


Exposing methods to JS

如果我们想注册怎么办广播接收器不是在应用程序上启动,而是稍后,然后从TypeScript中的React Native模块调用它? 来了@ReactMehod注解。 只需将一个方法添加到您的模块类即可:

@ReactMethod
public void startTrackingAudioJackPlug() {
    registerBroadcastReceiver();
}

现在,在任何TypeScript文件中,我们都可以从反应性的:

import { NativeModules } from 'react-native'

并使用直接从NativeModules对象调用它:

NativeModules.MyHeadsetLibModule.startTrackingAudioJackPlug()

Getting callback from native module

最后修改-让有关耳机插入的消息不按本机吐司显示,而是一些React Native警报显示。 为此,我们必须发出有关将耳机从本机模块插入JS模块的信息。 在本机代码中添加以下内容:

reactContext
    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
    .emit(eventName, params);
  1. eventName是串 object and identifies emitted message参数是可写地图对象并包含简单键值集合中的参数

现在,只需在JS模块中注册侦听器即可接收发出的消息。 进口DeviceEventEmitter从“反应性的”并在其中添加此代码componentDidMount方法:

DeviceEventEmitter.addListener('CustomNameOfTheEvent', function(e: Event) {

    /*
        Here you can display an alert.
        Get parameters values from event like this:
        let parameter = e["key"]
    */

})

而已。 我们刚刚实现了带有双向通信的本机功能。

from: https://dev.to//brightdevs/putting-native-in-react-native-on-android-13g7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值