我正在开发一个作为桥梁的应用程序在Xamarin和React Native之间。我遵循这个GitHub项目
https://github.com/voydz/xamarin-react-native
这是我的NativePackage.cs代码——
using Com.Facebook.React.Bridge;
using Com.Facebook.React.Uimanager;
using Com.Facebook.React;
using Java.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.Widget;
using Android.Content;
namespace ReactNative.Droid
{
public class NativePackage : Java.Lang.Object, IReactPackage
{
public IList<INativeModule> CreateNativeModules(ReactApplicationContext context)
{
var module = new NativeModule(context);
var list = new List<INativeModule> { module };
Console.WriteLine("Hello CreateNativeModules");
return list;
}
public IList<ViewManager> CreateViewManagers(ReactApplicationContext context)
{
Console.WriteLine("Hello CreateViewManagers");
return new List<ViewManager> { };
}
}
public class NativeModule : ReactContextBaseJavaModule
{
public NativeModule(ReactApplicationContext reactContext) : base(reactContext)
{
Console.WriteLine("Hello NativeModule");
}
public override string Name => "XNativeModule";
[Export("Foo")]
[ReactMethod]
public void Foo()
{
Console.WriteLine("Hello Native World");
Toast.MakeText(ReactApplicationContext, "Hello Native World", ToastLength.Long).Show();
}
}
}
下面是我的MainActivity代码using Android.App;
using Android.OS;
using Com.Facebook.React;
using Com.Facebook.React.Shell;
using Com.Facebook.React.Common;
using Android.Views;
using Com.Facebook.React.Modules.Core;
using Android.Support.V7.App;
using Android.Content;
using Android.Net;
using Android.Provider;
using ReactNative.Droid;
namespace SampleApp.Droid
{
[Activity(Label = "XamarinReactNative", MainLauncher = true, Icon = "@mipmap/icon", Theme = "@style/Theme.AppCompat.Light.NoActionBar")]
public class MainActivity : AppCompatActivity, IDefaultHardwareBackBtnHandler
{
ReactRootView mReactRootView;
ReactInstanceManager mReactInstanceManager;
private const int OVERLAY_PERMISSION_REQ_CODE = 1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
if (!Settings.CanDrawOverlays(this))
{
Intent intent = new Intent(Settings.ActionManageOverlayPermission, Uri.Parse("package:" + PackageName));
StartActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
}
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.Builder()
.SetApplication(Application)
.SetBundleAssetName("index.android.bundle")
.SetJSMainModulePath("index")
.AddPackage(new MainReactPackage())
#if DEBUG
.SetUseDeveloperSupport(true)
#else
.SetUseDeveloperSupport(false)
#endif
.SetInitialLifecycleState(LifecycleState.Resumed)
.Build();
mReactRootView.StartReactApplication(mReactInstanceManager, "MyReactNativeApp", null);
SetContentView(mReactRootView);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (requestCode == OVERLAY_PERMISSION_REQ_CODE)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
if (!Settings.CanDrawOverlays(this))
{
// SYSTEM_ALERT_WINDOW permission not granted...
}
}
}
}
protected override void OnPause()
{
base.OnPause();
if (mReactInstanceManager != null)
{
mReactInstanceManager.OnHostPause(this);
}
}
protected override void OnResume()
{
base.OnResume();
if (mReactInstanceManager != null)
{
mReactInstanceManager.OnHostResume(this, this);
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if (mReactInstanceManager != null)
{
mReactInstanceManager.OnHostDestroy(this);
}
}
public override void OnBackPressed()
{
if (mReactInstanceManager != null)
{
mReactInstanceManager.OnBackPressed();
}
else
{
base.OnBackPressed();
}
}
public void InvokeDefaultOnBackPressed()
{
base.OnBackPressed();
}
public override bool OnKeyUp(Keycode keyCode, KeyEvent e)
{
if (keyCode == Keycode.Menu && mReactInstanceManager != null)
{
mReactInstanceManager.ShowDevOptionsDialog();
return true;
}
return base.OnKeyUp(keyCode, e);
}
}
}
下面是我的index.js代码import React, { Component } from 'react';
import {
AppRegistry,
Platform,
StyleSheet,
Text, Button,
View,NativeModules
} from 'react-native';
console.log(NativeModules);
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload this is part of React,n' +
'Shake or press menu button for dev menu',
});
const {XNativeModule}=NativeModules;
const RNHelloWorld=()=> {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Hey there Judson! This is React native project
</Text>
<Text style={styles.instructions}>
To get started, edit App.js
</Text>
<Text style={styles.instructions}>
{instructions}
</Text>
<Button onPress={() => XNativeModule.Foo()} title="Call Native Module" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
// Module name
AppRegistry.registerComponent('MyReactNativeApp', () => RNHelloWorld);
当我点击按钮时,我得到以下错误。
undefined is not an object (evaluating 'u.Foo')
当前在我的代码中,当我调用xnative emodule . foo ()从我的JavaScript代码中,React Native bridges对本地模块的调用通过使用消息队列向本机端发送消息。在本机端,Xamarin运行时接收消息并将其路由到适当的本机模块。在本例中,它将调用xnativeemodule类中定义的Foo()方法. Xamarin的。Android的ReactContextBaseJavaModule类用于创建可从React native JavaScript代码调用的本地模块。但这对我不起作用。我不知道如何解决这个问题。有什么建议吗?
由于Foo不是一个类方法,您可以从按钮按下删除this
<Button onPress={() => XNativeModule.Foo()} title="Call Native Module" />
我通过添加NativePackage类修复了这个问题在ReactInstanceManager. 本机包类由Foo方法组成,因为NativePackage类未注册我们得到未定义错误的Foo方法. 这是我在MainActivity中的变化代码
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.Builder()
.SetApplication(Application)
.SetBundleAssetName("index.android.bundle")
.SetJSMainModulePath("index")
.AddPackage(new MainReactPackage())
.AddPackage(new NativePackage())
#if DEBUG
.SetUseDeveloperSupport(true)
#else
.SetUseDeveloperSupport(false)
#endif
.SetInitialLifecycleState(LifecycleState.Resumed)
.Build();
你可以看到AddPackage(new NativePackage())
在我的MainActivity代码。这修复了它,我能够部署应用程序没有任何异常。