繁体   English   中英

从集成到现有 Android 应用程序中的 React Native 应用程序获取结果

[英]Get a result from a react native app integrated into an existing android app

我发现很多文章都在谈论如何将 react native 集成到现有的 android 应用程序中。 但是他们都没有解释如何从本机代码中获取结果,以便直接在 Java android 源代码中使用它。

说明:我有一个 React Native 应用程序,它正在执行特定的工作并在弹出窗口中显示结果。 我想集成这个应用程序(进行必要的修改),以便能够将这个特定的结果放入我的 android Java 源代码中,而不是将它显示到一个 react native 弹出窗口中。

我搜索了所有互联网,但一无所获。

也许我不明白你想要做什么..但是你不能只是构建一个本机模块,让你的React Native应用程序调用该函数来完成将数据传递给你的本机代码吗?

假设你有一个应用程序的React Native部分,它将用户的名字和姓氏作为输入,然后点击提交。

您可以正常编写RN javascript:将2个TextInput字段及其值映射到您的状态,使用带有onPress处理程序的Button。 在onPress处理程序中,您将调用Native Module并传递参数

import { 
    NativeModules
} from 'react-native';

const NativeNameSubmission = NativeModules.NameSubmission;

...

    <Button
        onPress={() => NativeNameSubmission.submitName(this.state.firstName, this.state.lastName)}
        title="Submit"/>

您的本机模块看起来像这样:

public class RCTNameSubmission extends ReactContextBaseJavaModule {

    public RCTNameSubmission(ReactApplicationContext reactContext) {
        super(reactContext);
    }

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

    @ReactMethod
    public void submitName(String firstName, String lastName) {
        // save the name data for later use
        ...
        // Exit React App
        getCurrentActivity().finish();
    }
}

为了从您开始的活动中获得结果,您的模块需要能够访问您的活动参考。
这有两个解决方案:
- 将模块声明为活动的内部类
- 在模块的构造函数中传递活动的引用

但是,请记住,您的模块需要在ReactPackage ,而ReactPackage是一个接口,因此如果您需要,可以让您的ReactActivity实现接口(而不是创建新类)。

这是一个使用inner class和实现ReactPackage的活动的完整工作示例:

public class MyReactActivity extends AppCompatActivity 
    implements DefaultHardwareBackBtnHandler, ReactPackage
{
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                // This activity is also a "ReactPackage"
                .addPackage(this)
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactComponent", null);

        setContentView(mReactRootView);
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        // The module is added to the ReactPackage
        modules.add(new TestModule(reactContext));
        return modules;
    }

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

    // Module definition as an inner class
    public class TestModule extends ReactContextBaseJavaModule {
        public TestModule(ReactApplicationContext reactContext) {
            super(reactContext);
        }

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

        // The function you'll call from React Native
        @ReactMethod
        public void closewithresult(float datafromreact) {
            // Set a result
            Bundle bundle = new Bundle();
            bundle.putFloat("result", datafromreact);
            setResult(Activity.RESULT_OK, (new Intent()).putExtras(bundle));

            // Close the activity
            finish();
        }
    }

    /*
     * Other overrided functions 
     * (not relevant for this question)
     */ 
    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
    }

    @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
            mReactInstanceManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

}

然后,您可以像这样启动ReactActivity

Intent intent = new Intent(getApplicationContext(), MyReactActivity.class);
startActivityForResult(intent, 123);

得到这样的结果:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 123 && resultCode == Activity.RESULT_OK) {
        float result = data.getExtras().getFloat("result");
        // Do whatever you want with "result"
    }
}

并在React中使用它:

import { NativeModules } from 'react-native';
// [...]
// Call the function
NativeModules.TestModule.closewithresult(654.532);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM