自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

React Native中的Android原生模塊

移動(dòng)開(kāi)發(fā) Android
當(dāng)使用 React Native 開(kāi)發(fā) Android 應(yīng)用時(shí),你可能需要使用沒(méi)有被 React Native 封裝的模塊。但你可以使用 Java 編寫原生模塊,然后選擇性的暴露公共接口到 React Native。

[[176954]]

當(dāng)使用 React Native 開(kāi)發(fā) Android 應(yīng)用時(shí),你可能需要使用沒(méi)有被 React Native 封裝的模塊。但你可以使用 Java 編寫原生模塊,然后選擇性的暴露公共接口到 React Native。一起來(lái)試一下!

我們要寫一個(gè)什么東西

在寫這篇文章時(shí),React Native 包含了 ImagePickerIOS 組件,但是在 Android 平臺(tái)上卻沒(méi)有對(duì)應(yīng)的 ImagePicker 組件。我們接下來(lái)就要為 Android 構(gòu)建一個(gè)簡(jiǎn)單的、和 ImagePickerIOS 大致相仿的 ImagePicker。 

編寫一個(gè) React Native 的 Android 原生模塊需要以下步驟:

  1. 創(chuàng)建一個(gè) ReactPackage,把很多模塊(Native 和 Javascript)包含在一起,然后在 MainActivity 中的 getPackages 方法引用。
  2. 創(chuàng)建一個(gè) Java 類,繼承 ReactContextBaseJavaModule 并實(shí)現(xiàn)需要的接口,然后注冊(cè)到我們的 ReactPackage。
  3. 覆寫上述類的 getName 方法,這個(gè)方法會(huì)作為 Javascript 的調(diào)用方法名。
  4. 使用 @ReactMethod 注解把需要的公共方法暴露給 Javascript。
  5. ***,在 Javascript 中通過(guò) NativeModules 導(dǎo)入你的模塊。

讓我們一起實(shí)踐一下。

創(chuàng)建一個(gè) ReactPackage

啟動(dòng) AndroidStudio 并且導(dǎo)航到 MyApp/android/app/src/main/java/com/myapp/MainActivity.java。它應(yīng)該看起來(lái)像這樣:

  1. package com.myapp; 
  2.  
  3. import com.facebook.react.ReactActivity; 
  4. import com.facebook.react.ReactPackage; 
  5. import com.facebook.react.shell.MainReactPackage; 
  6.  
  7. import java.util.Arrays; 
  8. import java.util.List; 
  9.  
  10. public class MainActivity extends ReactActivity { 
  11.  
  12.     @Override 
  13.     protected String getMainComponentName() { 
  14.         return "MyApp"
  15.     } 
  16.  
  17.     @Override 
  18.     protected boolean getUseDeveloperSupport() { 
  19.         return BuildConfig.DEBUG; 
  20.     } 
  21.  
  22.     @Override 
  23.     protected List<ReactPackage> getPackages() { 
  24.         return Arrays.<ReactPackage>asList( 
  25.             new MainReactPackage() 
  26.         ); 
  27.     } 
  28.  

我們先來(lái)引入一個(gè)尚未定義的包:

  1. import com.myapp.imagepicker.*; // import the package 
  2.  
  3. public class MainActivity extends ReactActivity { 
  4.     @Override 
  5.     protected List<ReactPackage> getPackages() { 
  6.         return Arrays.<ReactPackage>asList( 
  7.             new MainReactPackage(), 
  8.             new ImagePickerPackage() // include it in getPackages 
  9.         ); 
  10.     } 
  11.  

現(xiàn)在我們來(lái)編寫那個(gè)包。我們將會(huì)為它創(chuàng)建一個(gè)叫 imagepicker 的新目錄并且寫入 ImagePickerPackage:

  1. package com.myapp.imagepicker; 
  2.  
  3. import com.facebook.react.ReactPackage; 
  4. import com.facebook.react.bridge.JavaScriptModule; 
  5. import com.facebook.react.bridge.NativeModule; 
  6. import com.facebook.react.bridge.ReactApplicationContext; 
  7. import com.facebook.react.uimanager.ViewManager; 
  8.  
  9. import java.util.ArrayList; 
  10. import java.util.Collections; 
  11. import java.util.List; 
  12.  
  13. public class ImagePickerPackage implements ReactPackage { 
  14.     @Override 
  15.     public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { 
  16.         List<NativeModule> modules = new ArrayList<>(); 
  17.  
  18.         modules.add(new ImagePickerModule(reactContext)); 
  19.  
  20.         return modules; 
  21.     } 
  22.  
  23.     @Override 
  24.     public List<Class<? extends JavaScriptModule>> createJSModules() { 
  25.         return Collections.emptyList(); 
  26.     } 
  27.  
  28.     @Override 
  29.     public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { 
  30.         return Collections.emptyList(); 
  31.     } 
  32.  

現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)包并且包含進(jìn) MainActivity 中了。

創(chuàng)建一個(gè) ReactContextBaseJavaModule

我們將會(huì)以創(chuàng)建 ImagePickerModule 開(kāi)始,繼承 ReactContextBaseJavaModule。

  1. package com.myapp.imagepicker; 
  2.  
  3. import com.facebook.react.bridge.ReactContextBaseJavaModule; 
  4.  
  5. public class ImagePickerModule extends ReactContextBaseJavaModule { 
  6.     public ImagePickerModule(ReactApplicationContext reactContext) { 
  7.         super(reactContext); 
  8.     } 
  9.  

這是一個(gè)好的開(kāi)始,為了 React Native 能從 NativeModules 找到我們的模塊,我們需要覆寫 getName 方法。

  1. @Override 
  2. public String getName() { 
  3.     return "ImagePicker"
  4.  

我們現(xiàn)在有了一個(gè)可以被 JavaScript 代碼導(dǎo)入的 native 模塊,讓它做些有趣的事情吧。

暴露方法

ImagePickerIOS 定義了 openSelectDialog 方法,可以傳遞配置對(duì)象、失敗、成功的回調(diào)。讓我們?cè)? ImagePickerModule 中定義一個(gè)相似的方法。

  1. import com.facebook.react.bridge.Callback; 
  2. import com.facebook.react.bridge.ReadableMap; 
  3.  
  4. public class ImagePickerModule extends ReactContextBaseJavaModule { 
  5.     @ReactMethod 
  6.     public void openSelectDialog(ReadableMap config, Callback successCallback, Callback cancelCallback) { 
  7.         Activity currentActivity = getCurrentActivity(); 
  8.      
  9.         if (currentActivity == null) { 
  10.             cancelCallback.invoke("Activity doesn't exist"); 
  11.             return
  12.         } 
  13.     } 
  14.  

這里我們從 React Native 中導(dǎo)入了 Callback 和 ReadableMap 來(lái)對(duì)應(yīng) JavaScript 中的 function 和 object。我們?yōu)檫@個(gè)方法加上@ReactMethod 注解,從而使它作為 ImagePicker 的一部分被 JavaScript 引用。

在方法體中我們獲取當(dāng)前的 activity,如果沒(méi)有獲取到 activity,就調(diào)用 cancel 的回調(diào)方法。我們現(xiàn)在有了一個(gè)可以運(yùn)行的方法,但是它還不能做任何有趣的事情。讓我們用它打開(kāi)相冊(cè)。

  1. public class ImagePickerModule extends ReactContextBaseJavaModule { 
  2.     private static final int PICK_IMAGE = 1; 
  3.  
  4.     private Callback pickerSuccessCallback; 
  5.     private Callback pickerCancelCallback; 
  6.  
  7.     @ReactMethod 
  8.     public void openSelectDialog(ReadableMap config, Callback successCallback, Callback cancelCallback) { 
  9.         Activity currentActivity = getCurrentActivity(); 
  10.  
  11.         if (currentActivity == null) { 
  12.             cancelCallback.invoke("Activity doesn't exist"); 
  13.             return
  14.         } 
  15.  
  16.         pickerSuccessCallback = successCallback; 
  17.         pickerCancelCallback = cancelCallback; 
  18.  
  19.         try { 
  20.             final Intent galleryIntent = new Intent(); 
  21.  
  22.             galleryIntent.setType("image/*"); 
  23.             galleryIntent.setAction(Intent.ACTION_GET_CONTENT); 
  24.  
  25.             final Intent chooserIntent = Intent.createChooser(galleryIntent, "Pick an image"); 
  26.  
  27.             currentActivity.startActivityForResult(chooserIntent, PICK_IMAGE); 
  28.         } catch (Exception e) { 
  29.             cancelCallback.invoke(e); 
  30.         } 
  31.     } 
  32.  

首先,我們?cè)O(shè)置了回調(diào),然后,我們創(chuàng)建了一個(gè) Intent 并把它傳遞給 startActivityForResult。***,我們把所有的東西都放在 try/catch 塊中來(lái)處理可能發(fā)生的異常。

當(dāng)你調(diào)用 openSelectDialog 時(shí),你應(yīng)該可以看到一個(gè)相冊(cè)了。然而,當(dāng)你選擇一張圖片時(shí),相冊(cè)并不做任何事情。為了能夠處理圖片數(shù)據(jù),我們需要在模塊中處理 activity 的返回值。

首先,我們需要在 react context 中添加 activity event listener:

  1. public class ImagePickerModule extends ReactContextBaseJavaModule implements ActivityEventListener { 
  2.     public ImagePickerModule(ReactApplicationContext reactContext) { 
  3.         super(reactContext); 
  4.         reactContext.addActivityEventListener(this); 
  5.     } 
  6.  

現(xiàn)在我們可以獲取到相冊(cè)返回的數(shù)據(jù)了。

  1. @Override 
  2. public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { 
  3.     if (pickerSuccessCallback != null) { 
  4.         if (resultCode == Activity.RESULT_CANCELED) { 
  5.             pickerCancelCallback.invoke("ImagePicker was cancelled"); 
  6.         } else if (resultCode == Activity.RESULT_OK) { 
  7.             Uri uri = intent.getData(); 
  8.  
  9.             if (uri == null) { 
  10.                 pickerCancelCallback.invoke("No image data found"); 
  11.             } else { 
  12.                 try { 
  13.                     pickerSuccessCallback.invoke(uri); 
  14.                 } catch (Exception e) { 
  15.                     pickerCancelCallback.invoke("No image data found"); 
  16.                 } 
  17.             } 
  18.         } 
  19.     } 
  20.  

在這里我們應(yīng)該可以通過(guò) success callback 獲取到圖片 URI。

  1. NativeModules.ImagePicker.openSelectDialog( 
  2.   {}, // no config yet  
  3.   (uri) => { console.log(uri) },  
  4.   (error) => { console.log(error) } 
  5.  

為了和 ImagePickerIOS 的表現(xiàn)大致相仿,我們可以允許用戶選擇圖片、視頻或者直接打開(kāi)相機(jī)。這些功能的寫法和上面基本一致,我們將會(huì)把它留給讀者作為練習(xí)。

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2018-06-13 16:38:33

React Nativ組件Android

2015-09-22 09:50:36

FacebookAndroid

2017-01-04 10:18:00

React NativScrollViewAndroid

2015-10-10 16:02:36

React NativAndroid

2015-03-30 12:13:23

React NativiOS

2017-06-20 12:48:55

React Nativ自定義模塊Note.js

2016-10-13 19:01:59

React NativUbuntu

2016-08-12 13:55:06

2023-06-24 17:09:06

React前端

2024-07-08 00:00:07

2016-08-12 08:49:46

React NativFacebookNative

2017-09-11 14:35:34

編輯器開(kāi)發(fā)環(huán)境React

2019-08-19 08:14:52

深度鏈接iOSAndroid

2023-01-29 08:00:00

Instagram濾鏡圖片編輯

2022-07-28 14:33:32

webviewweb頁(yè)面

2017-01-09 16:40:07

React NatiAndroid 開(kāi)發(fā)

2016-08-15 13:34:37

React NativiOSjs入口

2017-03-09 13:29:04

ReactNative JSPatch

2017-03-21 21:37:06

組件UI測(cè)試架構(gòu)

2024-01-19 09:03:06

ReactTypeScripFlexbox
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)