2017-10-20 26 views
8

我发现了很多关于如何将反应本机集成到现有Android应用程序中的文章。但是他们都没有解释如何从反应原生代码中得到结果以便直接在Java android源代码中使用它。从反应本机应用程序集成到现有的Android应用程序中获得结果

说明:我有一个反应本机应用程序,它正在执行特定作业并在弹出窗口中显示结果。 我想整合这个应用程序(做必要的修改),以便能够将此特定结果导入到我的Android Java源代码中,而不是将其显示到反应本机弹出窗口中。

我搜索了所有的互联网,但没有发现任何关于此。

+0

我不擅长本地代码,但不能运行一个新的本地方法与所需的数据作为参数? – bennygenel

+0

我认为你应该引用'android intent'来达到你的目标,在你的java里面使用intent来引起你的反应,然后用结果来回想https://facebook.github.io/react-native/releases/0.21/docs /intentandroid.html –

回答

3

为了得到一个结果,从你开始将该活动,你的模块需要访问你的活动的参考。
这里有两种解决方案:
- 声明模块作为一个内部类活动的
- 通过在模块

中的构造您的活动的参考,但,请记住,你的模块需要使用一个ReactPackageReactPackage是一个接口,所以如果你想让你的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" 
    } 
} 

And jus t在反应中使用它:

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处理,你会打电话给你的本机模块并通过参数

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(); 
    } 
} 
+0

我认为这是一个很好的部分,但我想在调用NativeNameSubmission时关闭React Native应用程序。submitName()'并直接在负责React Native应用程序活动的实例的活动中使用结果(在您的案例中为'firstName'和'lastName')。 – Marc

+0

以意图启动RN活动,并让启动它的活动侦听onActivityResult。我添加了代码来关闭模块中的RN应用程序(getCurrentActivity()。finish();)。在模块中,您可以保存数据供以后使用原始活动,或者您可以将其传回onActivityResult –

相关问题