5

我正在开发一个 React Native 应用程序并尝试从 android 访问 Native Module。我正在关注这个官方文档 在此处输入链接描述

创建本机模块后,当我尝试在 javaScript 类中访问它时,它显示错误“typeError: null is not an object (Evaluating _ToastExample.default.show)”

ToastModule.java

package com.awesomeproject;

import android.widget.Toast;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.util.Map;
import java.util.HashMap;

public class ToastModule extends ReactContextBaseJavaModule {
  private static ReactApplicationContext reactContext;

  private static final String DURATION_SHORT_KEY = "SHORT";
  private static final String DURATION_LONG_KEY = "LONG";

  ToastModule(ReactApplicationContext context) {
    super(context);
    reactContext = context;
  }

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

  @Override
  public Map<String, Object> getConstants() {
    final Map<String, Object> constants = new HashMap<>();
    constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
    constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
    return constants;
  }

  @ReactMethod
  public void show(String message, int duration) {
    Toast.makeText(getReactApplicationContext(), message, duration).show();
  }
}

CustomToastPackage.java

package com.awesomeproject;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CustomToastPackage implements ReactPackage {

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

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

    modules.add(new ToastModule(reactContext));

    return modules;
  }

}

在 MainApplication.java 中插入了这个片段

 protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
    // Packages that cannot be autolinked yet can be added manually here, for example:
    // packages.add(new MyReactNativePackage());
    packages.add(new CustomToastPackage()); // <-- Add this line with your package name.
    return packages;
  }

ToastExample.js

import {NativeModules} from 'react-native';
module.exports = NativeModules.ToastExample;

App.js 这里我只是想从 Android Native Module 调用那个简单的 Toast 函数。

import React, { Component } from 'react';
import EmojiDict from './components/EmojiDict';
import ToastExample from './ToastExample';

export default class App extends Component {

  componentDidMount(){
    ToastExample.show('Awesome', ToastExample.SHORT);
  }

  render() {
        return <
            EmojiDict />;
    }
}

附上错误截图。 在此处输入图像描述

我是 ReactNative 的新手,所以请帮我解决这个问题。提前致谢。

4

5 回答 5

2

我的就是这样解决的

修改上述文件的2个重要步骤

1.修改ToastModule.java文件的getName

 @Override
  public String getName() {
    return "ToastModule";   // ToastExample to ToastModule
  }

2.修改ToastExample.js文件

import {NativeModules} from 'react-native';

export default NativeModules.ToastModule;  // ToastExample to ToastModule

但是不知道为什么,好尴尬,祝你好运!

于 2021-05-10T14:28:28.600 回答
1

我有同样的问题,杀死了我一天多。在谷歌搜索时,我在问题中遇到了上述@Mudasir 的评论。在我的情况下,这也是一个路径问题,在我的 index.js 文件中:我使用不同的名称(Toast)调用本机模块但在 index.js 文件中我声明为 ToastModule:我的 index.js 文件:

import { NativeModules } from 'react-native';

const { ToastModule} = NativeModules;

export default ToastModule;

从我导入后的 app.js 中:

import ToastModule from 'react-native-custom-toast-module';
于 2020-07-08T09:19:16.157 回答
1

问题可能是您混合了两个不同的模块名称:ToastModuleToastExample.

包含:

public String getName() {
  return "ToastExample";
}

我有同样的问题,getName()不匹配是它的原因。

于 2021-01-27T00:41:07.463 回答
0

我做的一切都正确,但问题是,我只是通过刷新来使用代码,但我们需要重建应用程序(重新运行)

     react-native run-android

不仅如此,而且每次我们对原生 android(java) 代码进行一点更改时,我们都必须重新运行

于 2021-01-25T12:55:53.693 回答
0

在 MainApplication 中,您可以看到 getPackages() 方法在 ReactNativeHost 中已经可用

您需要将该包添加到

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
        List<ReactPackage> packages = new PackageList(this).getPackages();
        packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider));
        //here you need to add
        packages.add(new CustomToastPackage());
        return packages;
    }

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

    @Override
    protected @Nullable
    String getJSBundleFile() {
        if (BuildConfig.DEBUG) {
            return super.getJSBundleFile();
        } else {
            return UpdatesController.getInstance().getLaunchAssetFile();
        }
    }

    @Override
    protected @Nullable
    String getBundleAssetName() {
        if (BuildConfig.DEBUG) {
            return super.getBundleAssetName();
        } else {
            return UpdatesController.getInstance().getBundleAssetName();
        }
    }
};
于 2020-04-28T07:14:10.557 回答