反応-ネイティブを時々ネイティブAPIにアクセスする必要がありますが、公式には、手動でそのようなハードウェア・インターフェースの一部を呼び出す必要があるなどのコール・アンドリューストーストなどのネイティブコードを呼び出す必要があり、この時間をパッケージ化しませんでした。この記事の文書がどのようにAndroidとiOSのネイティブメソッドを呼び出します。
iOS版
まず、作成しbridge
たファイルを、私はここ継承RCTEventEmitterクラス、MessageBridgeと呼ばれている、および以下に示すように、RCTBridgeModuleプロトコルを実現します。
1 2 3 4 5 6 7
|
#import <財団/ Foundation.h> の#import <リアクト/ RCTBridgeModule.h> の#import <リアクト/ RCTEventEmitter.h> の#import <財団/ Foundation.h> @interface MessageBridge:RCTEventEmitter <RCTBridgeModule>
@終わり
|
また、クラスRCT_EXPORT_MODULE()マクロを追加する必要がありRCTBridgeModuleプロトコルを達成するために。このマクロは、彼はあなたがJavascriptが名を指定するように呼びかけている指定した場合、クラスの現在の名前をエクスポートし、デフォルトにパラメータを渡すないだろうと仮定して、JavaScriptにモジュールをエクスポートする方法です。たとえば、次のコードモジュール名には、JavaScriptに見られますMessageBridge
。
1 2 3 4
|
#importを"MessageBridge.h" @implementation MessageBridge RCT_EXPORT_MODULE()。 @終わり
|
メッセージングは、私は1つのネイティブプラットフォーム、メッセージをプッシュするネイティブJavaScriptのプラットフォームから直接、コールバックメッセージである、2つのカテゴリに分けます。
コールバックメッセージ
iOS版が反応-ネイティブダイレクトを実装することを約束します。ES2016を使用しasync/await
たキーワードが大幅にコードを簡素化することができます。
1 2 3 4 5 6 7 8 9 10 11 12
|
RCT_REMAP_METHOD(のgetMessage、:( NSStringの*)メッセージ findEventsWithResolver:(RCTPromiseResolveBlock)解決 リジェクト:(RCTPromiseRejectBlockは)拒否) { NSDictionaryの*データ= @ { "成功" @:@ YES、@ "メッセージ":[メッセージstringByAppendingString:@」(約束) "]}。 (データ){もし 解決(データ)。 }他{ NSError *誤差= [[NSError ALLOC] initWithDomain:@ "ショー"コード:200ユーザー情報:なし]。 (エラーは、「何のイベントはありませんでした」@「no_events」、@)拒否。 } }
|
だから、JavaScriptが使用し、約束を得ることができawait
、コールバックの値を取得するためのキーワードを。
1 2 3 4 5 6 7 8 9
|
非同期のgetMessage(){ しようと { VARのデータ=が待つ MessageBridge.getMessage('ゲットメッセージ'を)。この .setState({ "のgetMessage":data.message})。コンソールの.log(データ)。 } キャッチ(E){ コンソール .ERROR(E); } }
|
プッシュメッセージ
いくつかの特別な事情がネイティブに反応するようにネイティブプラットフォームからのメッセージをプッシュするために、我々は、実装することができますsupportedEvents
メソッドを呼び出した後、self sendEventWithNam::
プッシュメッセージで完了することができます。
注supportedEventsが達成されなければならないか、エラーになります。
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#importを"MessageBridge.h" @implementation MessageBridge RCT_EXPORT_MODULE()。 RCT_REMAP_METHOD(pushMessage、:( NSStringの*)メッセージ) { NSDictionaryの*データ= @ { "成功" @:@ YES、@ "メッセージ":[メッセージstringByAppendingString:@ "()イベントを送信します"]}。 [自己sendEventWithName: "PushMessage"ボディ@:データ]; }
- (NSArrayの<NSStringの*> *)supportedEvents { [ "PushMessage" @]戻り@。 } @end
|
アンドロイド
まず、android/app/src/main/java/com/(your-app-name)/
フォルダの作成MessageBridge
、クラス、継承ReactContextBaseJavaModuleを。
そして、実装するJavaScript呼び出しに必要なクラス名を返すメソッドを、。ReactContextBaseJavaModule
getName
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
import android.support.annotation.Nullable; import android.widget.Toast;
import com.facebook.react.bridge.Arguments; 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 com.facebook.react.bridge.WritableMap; import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.bridge.Promise;
public class extends ReactContextBaseJavaModule { public String getName() { return "MessageBridge"; } }
|
然后在同一个目录下创建一个CustomReactPackages.java文件,这个文件用来导出自定的package名字,文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
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 CustomReactPackages implements ReactPackage{ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }
public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>();
modules.add(new MessageBridge(reactContext));
return modules; } }
|
最后在MainApplication.java文件中添加CustomToastPackage():
注意是MainApplication.java不是MainActivity.java,之前弄错了bug调的我怀疑人生。
1 2 3 4 5
|
protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new CustomToastPackages()); }
|
回调消息
安卓也可以直接实现一个Promise给React-Native。
1 2 3 4 5 6 7 8 9 10 11
|
@ReactMethod public void getMessage(String message, Promise promise) { try { WritableMap data = Arguments.createMap(); data.putString("status","success"); data.putString("message", message + " (promise)"); promise.resolve(data); } catch(IllegalViewOperationException e){ promise.reject("error", e); } }
|
其中注释@ReactMethod是为了将方法暴露给JavaScript。加了@ReactMethod后会将Java变量类型一一映射成JavaScript的变量类型
Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array
JavaScript端代码跟iOS一样,使用await
关键字就可以得到回调的值了。
1 2 3 4 5 6 7 8 9
|
async getMessage() { try { var data = await MessageBridge.getMessage('Get Message'); this.setState({ "getMessage": data.message }); console.log(data); } catch (e) { console.error(e); } }
|
推送消息
安卓中推送消息给React-Native
最简单的方法就是通过使用ReactContext
中的RCTDeviceEventEmitter
方法,如下面代码所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) { reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); }
@ReactMethod public void pushMessage(String message) { WritableMap data = Arguments.createMap(); data.putString("status","success"); data.putString("message",message + " (send event)"); this.sendEvent(this.mReactContext,"PushMessage",data); }
|
然后在JavaScript端可以直接使用DeviceEventEmitter
来监听事件
1 2 3 4 5
|
componentWillMount: function() { DeviceEventEmitter.addListener('keyboardWillShow' 、関数(E:イベント) { })。}
|
Demo 地址:https://github.com/cydjohn/RNNativeModules
オリジナル:ビッグボックス リアクトネイティブクロスプラットフォーム呼び出すコード