当前位置: 首页 > 科技观察

ReactNative中的AndroidNative模块

时间:2023-03-11 21:53:18 科技观察

使用ReactNative开发Android应用程序时,您可能需要使用ReactNative未包装的模块。但是您可以用Java编写本机模块,并可选择将公共接口公开给ReactNative。让我们一起来试试吧!我们要写点什么。在写这篇文章的时候,ReactNative已经包含了ImagePickerIOS组件,但是在Android平台上还没有对应的ImagePicker组件。我们的下一步是为Android构建一个与ImagePickerIOS大致相似的简单ImagePicker。编写一个ReactNativeAndroid原生模块需要以下步骤:创建一个ReactPackage,包含很多模块(Native和Javascript),然后在MainActivity中的getPackages方法中引用它。创建一个Java类,继承ReactContextBaseJavaModule并实现需要的接口,然后注册到我们的ReactPackage中。重写上述类的getName方法,该方法将作为Javascript的调用方法名。使用@ReactMethod注释将所需的公共方法公开给Javascript。***,通过Javascript中的NativeModules导入您的模块。让我们一起练习吧。创建一个ReactPackage启动AndroidStudio并导航到MyApp/android/app/src/main/java/com/myapp/MainActivity.java。它应该是这样的:@OverrideprotectedStringgetMainComponentName(){return"MyApp";}@OverrideprotectedbooleangetUseDeveloperSupport(){returnBuildConfig.DEBUG;}@OverrideprotectedListgetPackages(){returnArrays.asList(newMainReactPackage());先介绍一个}}尚未定义的包:importcom.myapp.imagepicker.*;//importthepackagepublicclassMainActivityextendsReactActivity{@OverrideprotectedListgetPackages(){returnArrays.asList(newMainReactPackage(),newImagePickerPackage()//includeitingetPackages);}}现在让我们写那个包。我们将为它创建一个名为imagepicker的新目录并编写ImagePickerPackage:packagecom.myapp.imagepicker;importcom.facebook.react.ReactPackage;importcom.facebook.react.bridge.JavaScriptModule;importcom.facebook.react.bridge.NativeModule;importcom...modules=newArrayList<>();modules.add(newImagePickerModule(reactContext));returnmodules;}@OverridepublicList>createJSModules(){returnCollections.emptyList();}@OverridepublicListcreateViewManagers(ReactApplicationContextreactContext){returnCollections.emptyList();}}现在我们已经创建了一个包并将其包含在MainActivity中。创建ReactContextBaseJavaModule我们将从创建ImagePickerModule开始,它继承自ReactContextBaseJavaModule。packagecom.myapp.imagepicker;importcom.facebook.react.bridge.ReactContextBaseJavaModule;publicclassImagePickerModuleextendsReactContextBaseJavaModule{publicImagePickerModule(ReactApplicationContextreactContext){super(reactContext);}}这是一个好的开始,为了让ReactNative从NativeModules中找到我们的模块,我们需要覆盖getName方法。@OverridepublicStringgetName(){return"ImagePicker";}我们现在有了一个可以通过JavaScript代码导入的本机模块,让我们让它做一些有趣的事情。暴露的方法ImagePickerIOS定义了openSelectDialog方法,可以传递配置对象,失败,成功回调。让我们在ImagePickerModule中定义一个类似的方法。importcom.facebook.react.bridge.Callback;importcom.facebook.react.bridge.ReadableMap;publicclassImagePickerModuleextendsReactContextBaseJavaModule{@ReactMethodpublicvoidopenSelectDialog(ReadableMapconfig,CallbacksuccessCallback,CallbackcancelCallback){ActivitycurrentActivity=getCurrentActivity();if(currentActivity==null){cancelCallback.invoke("Activitydoes'texist");return;}}}这里我们从ReactNative中引入了Callback和ReadableMap来对应JavaScript中的函数和对象。我们用@ReactMethod注释此方法,以便它可以作为ImagePicker的一部分被JavaScript引用。在方法体中,我们获取当前的activity,如果没有获取到activity,则调用cancel的回调方法。我们现在有了一个有效的方法,但它还没有做任何有趣的事情。让我们用它来打开相册。publicclassImagePickerModuleextendsReactContextBaseJavaModule{privatestaticfinalintPICK_IMAGE=1;privateCallbackpickerSuccessCallback;privateCallbackpickerCancelCallback;@ReactMethodpublicvoidopenSelectDialog(ReadableMapconfig,CallbacksuccessCallback,CallbackcancelCallback){ActivitycurrentActivity=getCurrentActivity();if(currentActivity==null){cancelCallback.invoke("Activitydoesn'texist");return;}pickerSuccessCallback=successCallback;pickerCancelCallback=cancelCallback;try{finalIntentgalleryIntent=newIntent();galleryIntent.setType("image/*");galleryIntent.setAction(Intent.ACTION_GET_CONTENT);finalIntentchooserIntent=ultentIntent.createChooser(galleryyIntent,"Pickanimage");ForcurrentActivctAction(chooserIntent),PICK_IMAGE);}catch(Exceptione){cancelCallback.invoke(e);}}}首先,我们设置回调,然后,我们创建一个Intent并将其传递给startActivityForResult。***,我们把所有的东西都放在try/catch块中来处理可能发生的异常。当您调用openSelectDialog时,您应该会看到一个相册。但是,当您选择图片时,图库不会执行任何操作。为了能够处理图像数据,我们需要在模块中处理activity的返回值。首先,我们需要在reactcontext中添加一个activity事件监听器:publicclassImagePickerModuleextendsReactContextBaseJavaModuleimplementsActivityEventListener{publicImagePickerModule(ReactApplicationContextreactContext){super(reactContext);reactContext.addActivityEventListener(this);}}现在我们可以拿到相册返回的数据了。@OverridepublicvoidonActivityResult(finalintrequestCode,finalintresultCode,finalIntentintent){if(pickerSuccessCallback!=null){if(resultCode==Activity.RESULT_CANCELED){pickerCancelCallback.invoke("ImagePickerwascancelled");}elseif(resultCode==Activity.RESULT_OK){Uriintent.getData();if(uri==null){pickerCancelCallback.invoke("Noimagedatafound");}else{try{pickerSuccessCallback.invoke(uri);}catch(Exceptione){pickerCancelCallback.invoke("Noimagedatafound");}}}}}到这里我们应该可以通过成功回调获取到图片URI了。NativeModules.ImagePicker.openSelectDialog({},//noconfigyet(uri)=>{console.log(uri)},(error)=>{console.log(error)})为了与ImagePickerIOS的行为类似,我们可以允许用户选择图片、视频或直接打开相机。这些函数的写法和上面基本一样,留给读者做习题。