【问题标题】:Access methods from .jar file in react native(android)react native(android)中.jar文件的访问方法
【发布时间】:2019-12-06 11:01:56
【问题描述】:

我想将本机编写的模块(java、Android)导入到我的 React Native 源代码中,用 JS 编写。

【问题讨论】:

标签: javascript java android reactjs react-native


【解决方案1】:

要访问您在 java 中实现的功能,您必须创建一个桥接器。您可以在 RN 文档站点中查看最新的说明*。

步骤,假设 React Native 0.61,对于一个 hello world,将在 react native app 目录(android 目录)内的 android 项目中实现: 1) 首先你创建一个简单的 POJO 类来返回到 react native 上下文中:

class MyData{
    private int timeSpentSleeping;

    public int getTimeSpentSleeping() {
        return timeSpentSleeping;
    }

    public void setTimeSpentSleeping(int timeSpentSleeping) {
        this.timeSpentSleeping = timeSpentSleeping;
    }

    @NonNull
    @Override
    public String toString() {
        Gson gson = new Gson();
        String json = gson.toJson(this);
        return json;
    }

    static MyData build(final int timeSpentSleeping){
        MyData newInstance = new MyData();
        newInstance.timeSpentSleeping = timeSpentSleeping;
        return newInstance;
    }
}

以及做某事并将此类的对象作为 javascript Promises 返回的 react 本机模块:

public class HelloPromiseModule extends ReactContextBaseJavaModule {
    public HelloPromiseModule(@NonNull ReactApplicationContext reactContext) {
        super(reactContext);
    }

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

    @ReactMethod
    public void foobar(Promise promise){
        Random r = new Random();
        final int timeToSleep = r.nextInt(1000);
        runThreadAndCallPromiseToJavascript(timeToSleep, promise);
    }
    //Cria um thread pra executar algo em paralelo
    private void runThreadAndCallPromiseToJavascript(final int timeToSleep,final Promise promise){
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(timeToSleep);
                    MyData result = MyData.build(timeToSleep);
                    promise.resolve(result.toString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    promise.reject(e);
                }
            }
        });
        t.run();
    }
}

现在,我们创建 React Native 包(不同于 java 包):

public class HelloWorldPackage implements ReactPackage{
    @NonNull
    @Override
    public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
        return Arrays.<NativeModule>asList(
                new HelloPromiseModule(reactContext));
    }

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

你的 react native 应用的 android 版本的最后一步是注册你的 HelloWorldPackage: 在你的 android 项目中的 MainApplication.java 中,在 getPackages() 中,在包列表中 (new PackageList(this)...):

packages.add(new HelloWorldPackage());

类似的东西:

protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          packages.add(new HelloWorldPackage());
          return packages;
        }

现在,让你的原生类进入 javascript 世界:

import {
  NativeModules,
} from 'react-native';
...
const {HelloPromise} = NativeModules;

你的原生类可以通过变量 HelloPromise 访问。 您可以在代码的 react native 端通过类似这样的方式获得 HelloPromise.foobar() 的结果:

async function handleHelloPromisesPress() {
   let result = await HelloPromise.foobar();
   console.log(result);
}

你可能注意到'result'是一个json,它的结构和我们一开始创建的POJO类是一样的。

【讨论】:

  • *更喜欢 facebook 文档而不是教程。大多数在最近(2019 年 12 月)发布的 RN 0.6 中已过时 *如果您的 android 项目有 DEX 问题,请将 minSdkVersion 提高到 24(至少)int build.gradle *您的应用程序将在 iOS 中崩溃,直到您移植您的jar 到 swift/objectivec 并构建原生 ios 桥。
猜你喜欢
  • 1970-01-01
  • 2022-08-19
  • 2022-06-28
  • 2016-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
相关资源
最近更新 更多