簡體   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