成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React Native 中的 Android 原生模塊

caiyongji / 2281人閱讀

摘要:當使用開發(fā)應用時,你可能需要使用沒有被封裝的模塊。但你可以使用編寫原生模塊,然后選擇性的暴露公共接口到。編寫一個的原生模塊需要以下步驟創(chuàng)建一個,把很多模塊和包含在一起,然后在中的方法引用。最后,在中通過導入你的模塊。

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

我們要寫一個什么東西

在寫這篇文章時,React Native 包含了 ImagePickerIOS 組件,但是在 Android 平臺上卻沒有對應的 ImagePicker 組件。我們接下來就要為 Android 構建一個簡單的、和 ImagePickerIOS 大致相仿的 ImagePicker。

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

創(chuàng)建一個 ReactPackage,把很多模塊(Native 和 Javascript)包含在一起,然后在 MainActivity 中的 getPackages 方法引用。

創(chuàng)建一個 Java 類,繼承 ReactContextBaseJavaModule 并實現(xiàn)需要的接口,然后注冊到我們的 ReactPackage。

覆寫上述類的 getName 方法,這個方法會作為 Javascript 的調用方法名。

使用 @ReactMethod 注解把需要的公共方法暴露給 Javascript。

最后,在 Javascript 中通過 NativeModules 導入你的模塊。

讓我們一起實踐一下。

創(chuàng)建一個 ReactPackage

啟動 AndroidStudio 并且導航到 MyApp/android/app/src/main/java/com/myapp/MainActivity.java。它應該看起來像這樣:

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 getPackages() {
        return Arrays.asList(
            new MainReactPackage()
        );
    }
}

我們先來引入一個尚未定義的包:

import com.myapp.imagepicker.*; // import the package

public class MainActivity extends ReactActivity {
    @Override
    protected List getPackages() {
        return Arrays.asList(
            new MainReactPackage(),
            new ImagePickerPackage() // include it in getPackages
        );
    }
}

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

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 createNativeModules(ReactApplicationContext reactContext) {
        List modules = new ArrayList<>();

        modules.add(new ImagePickerModule(reactContext));

        return modules;
    }

    @Override
    public List> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

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

創(chuàng)建一個 ReactContextBaseJavaModule

我們將會以創(chuàng)建 ImagePickerModule 開始,繼承 ReactContextBaseJavaModule

package com.myapp.imagepicker;

import com.facebook.react.bridge.ReactContextBaseJavaModule;

public class ImagePickerModule extends ReactContextBaseJavaModule {
    public ImagePickerModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }
}

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

@Override
public String getName() {
    return "ImagePicker";
}

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

暴露方法

ImagePickerIOS 定義了 openSelectDialog 方法,可以傳遞配置對象、失敗、成功的回調。讓我們在 ImagePickerModule 中定義一個相似的方法。

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 中導入了 CallbackReadableMap 來對應 JavaScript 中的 functionobject。我們?yōu)檫@個方法加上 @ReactMethod 注解,從而使它作為 ImagePicker 的一部分被 JavaScript 引用。
在方法體中我們獲取當前的 activity,如果沒有獲取到 activity,就調用 cancel 的回調方法。我們現(xiàn)在有了一個可以運行的方法,但是它還不能做任何有趣的事情。讓我們用它打開相冊。

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 successCallback, 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);
        }
    }
}

首先,我們設置了回調,然后,我們創(chuàng)建了一個 Intent 并把它傳遞給 startActivityForResult。最后,我們把所有的東西都放在 try/catch 塊中來處理可能發(fā)生的異常。

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

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

public class ImagePickerModule extends ReactContextBaseJavaModule implements ActivityEventListener {
    public ImagePickerModule(ReactApplicationContext reactContext) {
        super(reactContext);
        reactContext.addActivityEventListener(this);
    }
}

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

@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) }
)

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

相關閱讀

使用 React Native 構建 Facebook Paper 類似的 UI

作者往期佳作

ES6 Generators 工作原理
歡迎關注公眾號:MaxLeap_yidongyanfa

作者信息

原文作者: Ryan Linton
原文鏈接: http://t.cn/Rfadv1R
翻譯自MaxLeap團隊_前端研發(fā)人員:Henry Bai
MaxLeap技術博客首發(fā):https://blog.maxleap.cn/

活動預告

主題:手把手教你玩轉微信小程序,領先進入藍海市場
時間:11月23日
地點:上海徐匯宜山路888號21樓
報名url:http://t.cn/RfcM3Sa

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/80991.html

相關文章

  • React Native 原理

    摘要:對象和原生代碼交互對象可以和原生對象之間相互調用,關系如上圖。和本地代碼間的通信其中通信的特點是異步的序列化的批量的,對于大批量的通信事件可以將其分成幾部分,減少時間延遲參考 React Native簡介 React Native是一個建立在JavaScript和React上用于構建本地應用的框架,它具有React和JavaScript相似的代碼風格,編寫一次可以運行在多個平臺之上(>...

    jackzou 評論0 收藏0

發(fā)表評論

0條評論

caiyongji

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<