我正在开发一个React Native应用,并试图从android中访问本地模块。我按照这个官方文档请在此输入链接描述
创建了Native模块后,当我试图在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的新手,所以请帮我解决这个问题。先谢谢你了。
我有同样的问题,是杀了我一天多。在上网搜索的时候,我看到了上面@Mudasir的评论中的问题。在我的情况下,这也是一个路径问题,在我的index.js文件中:我用不同的名字(Toast)来调用native模块,但是在index.js文件中我声明为ToastModule:我的index.js文件。
import { NativeModules } from 'react-native';
const { ToastModule} = NativeModules;
export default ToastModule;
从app.js文件中我导入后,我的index.js文件是这样的。
import ToastModule from 'react-native-custom-toast-module';
在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();
}
}
};