React Native 中的 Android 原生模块
我们要写一个什么东西在写这篇文章时,React Native 包含了 ImagePickerIOS 组件,但是在 Android 平台上却没有对应的 ImagePicker 组件。我们接下来就要为 Android 构建一个简单的、和 ImagePickerIOS 大致相仿的 ImagePicker。
编写一个 React Native 的 Android 原生模块需要以下步骤:
让我们一起实践一下。 创建一个 ReactPackage启动 AndroidStudio 并且导航到 package com.myapp; import com.facebook.react.ReactActivity; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; import java.util.Arrays; import java.util.List; public class MainActivity extends ReactActivity { @Override protected String getMainComponentName() { return "MyApp"; } @Override protected boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage() ); } } 我们先来引入一个尚未定义的包: import com.myapp.imagepicker.*; // import the package public class MainActivity extends ReactActivity { @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(),new ImagePickerPackage() // include it in getPackages ); } } 现在我们来编写那个包。我们将会为它创建一个叫 package com.myapp.imagepicker; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; 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 ImagePickerPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new ImagePickerModule(reactContext)); return modules; } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } } 现在我们已经创建了一个包并且包含进 创建一个 ReactContextBaseJavaModule我们将会以创建 package com.myapp.imagepicker; import com.facebook.react.bridge.ReactContextBaseJavaModule; public class ImagePickerModule extends ReactContextBaseJavaModule { public ImagePickerModule(ReactApplicationContext reactContext) { super(reactContext); } } 这是一个好的开始,为了 React Native 能从 @Override public String getName() { return "ImagePicker"; } 我们现在有了一个可以被 JavaScript 代码导入的 native 模块,让它做些有趣的事情吧。 暴露方法
import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReadableMap; public class ImagePickerModule extends ReactContextBaseJavaModule { @ReactMethod public void openSelectDialog(ReadableMap config,Callback successCallback,Callback cancelCallback) { Activity currentActivity = getCurrentActivity(); if (currentActivity == null) { cancelCallback.invoke("Activity doesn't exist"); return; } } } 这里我们从 React Native 中导入了 public class ImagePickerModule extends ReactContextBaseJavaModule { private static final int PICK_IMAGE = 1; private Callback pickerSuccessCallback; private Callback pickerCancelCallback; @ReactMethod public void openSelectDialog(ReadableMap config,Callback cancelCallback) { Activity currentActivity = getCurrentActivity(); if (currentActivity == null) { cancelCallback.invoke("Activity doesn't exist"); return; } pickerSuccessCallback = successCallback; pickerCancelCallback = cancelCallback; try { final Intent galleryIntent = new Intent(); galleryIntent.setType("image/*"); galleryIntent.setAction(Intent.ACTION_GET_CONTENT); final Intent chooserIntent = Intent.createChooser(galleryIntent,"Pick an image"); currentActivity.startActivityForResult(chooserIntent,PICK_IMAGE); } catch (Exception e) { cancelCallback.invoke(e); } } } 首先,我们设置了回调,然后,我们创建了一个 当你调用 首先,我们需要在 react context 中添加 activity event listener: public class ImagePickerModule extends ReactContextBaseJavaModule implements ActivityEventListener { public ImagePickerModule(ReactApplicationContext reactContext) { super(reactContext); reactContext.addActivityEventListener(this); } } 现在我们可以获取到相册返回的数据了。 @Override public void onActivityResult(final int requestCode,final int resultCode,final Intent intent) { if (pickerSuccessCallback != null) { if (resultCode == Activity.RESULT_CANCELED) { pickerCancelCallback.invoke("ImagePicker was cancelled"); } else if (resultCode == Activity.RESULT_OK) { Uri uri = intent.getData(); if (uri == null) { pickerCancelCallback.invoke("No image data found"); } else { try { pickerSuccessCallback.invoke(uri); } catch (Exception e) { pickerCancelCallback.invoke("No image data found"); } } } } } 在这里我们应该可以通过 success callback 获取到图片 URI。 NativeModules.ImagePicker.openSelectDialog( {},// no config yet (uri) => { console.log(uri) },(error) => { console.log(error) } ) 为了和 相关阅读使用 React Native 构建 Facebook Paper 类似的 UI 作者往期佳作ES6 Generators 工作原理 作者信息原文作者: Ryan Linton 活动预告主题:手把手教你玩转微信小程序,领先进入蓝海市场 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |