首页 文章

从现有Android应用程序中集成的本机应用程序获取结果

提问于
浏览
7

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

解释:我有一个做出特定工作的本机应用程序,并在弹出窗口中显示结果 . 我想整合这个应用程序(进行必要的修改),以便能够将这个特定的结果导入我的android Java源代码,而不是将其显示到反应原生弹出窗口中 .

我搜索了所有的互联网,但没有发现这一点 .

2 回答

  • 3

    为了从您开始的活动中获得结果,您的模块需要能够访问您的活动参考 .
    这有两个解决方案:

    • 将模块声明为活动的内部类
    • 在模块的构造函数中传递活动的引用

    但是,请记住,您的模块需要在 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);
    
  • 3

    也许我不明白你想要做什么..但是你不能只是构建一个本机模块,让你的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();
        }
    }
    

相关问题