简体   繁体   English

从React-Native代码调用Android活动

[英]Call Android activity from React-Native code

I am using REACT-NATIVE to build android app. 我正在使用REACT-NATIVE来构建android应用。 I want to call android activity from React-Native code. 我想从React-Native代码中调用android活动。 (say when I clicked the button in my react native code, it should call android activity) (例如,当我单击我的反应本机代码中的按钮时,它应该调用android活动)

I have 4 class files 我有4个班级档案

  • MainActivity.java (created by react-native when opened in android studio) MainActivity.java(在Android Studio中打开时由react-native创建)
  • MainApplication.java (created by react-native) MainApplication.java(由react-native创建)
  • Login.java (android activity file) Login.java(Android活动文件)
  • Example.java (android activity file) Example.java(Android活动文件)

Want to achieve following flow: 要实现以下流程:

Login.java -> React-Native js -> Example.java Login.java-> React-Native js-> Example.java

I already went through following links, but unable to understand 我已经通过以下链接,但是无法理解

https://stackoverflow.com/a/32825290/4849554 https://stackoverflow.com/a/32825290/4849554

Similar question asked here 在这里问类似的问题

React Native Android: Showing an Activity from Java React Native Android:显示来自Java的活动

To start an Android activity, you need to create a custom native module. 要启动Android活动,您需要创建一个自定义的本机模块。 Assume one called ActivityStarter ; 假设一个叫做ActivityStarter it might be used from JavaScript as follows: 可以在JavaScript中使用它,如下所示:

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

export default class DemoComponent extends Component {
    render() {
        return (
        <View>
            <Button
                onPress={() => NativeModules.ActivityStarter.navigateToExample()}
                title='Start example activity'
            />
        </View>
        );
    }
}

ActivityStarter is just a Java class that implements a React Native Java interface called NativeModule . ActivityStarter只是一个Java类,实现了称为NativeModule的React Native Java接口。 The heavy lifting of this interface is already done by BaseJavaModule , so one normally extends either that one or ReactContextBaseJavaModule : 该接口的繁重工作已经由BaseJavaModule完成,因此通常可以扩展该接口或ReactContextBaseJavaModule

class ActivityStarterModule extends ReactContextBaseJavaModule {

    ActivityStarterModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

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

    @ReactMethod
    void navigateToExample() {
        ReactApplicationContext context = getReactApplicationContext();
        Intent intent = new Intent(context, ExampleActivity.class);
        context.startActivity(intent);
    }
}

The name of this class doesn't matter; 此类的名称无关紧要; the ActivityStarter module name exposed to JavaScript comes from the getName() method. 暴露给JavaScript的ActivityStarter模块名称来自getName()方法。

The default app generated by react-native init contains a MainApplication class that initializes React Native. react-native init生成的默认应用包含一个MainApplication类,该类初始化React Native。 Among other things it extends ReactNativeHost to override its getPackages method: 除其他外,它扩展了ReactNativeHost以覆盖其getPackages方法:

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new MainReactPackage()
    );
}

If you're adding React Native to an existing app, this page has you override your Activity 's onCreate as follows: 如果要将React Native添加到现有应用程序,则此页面将覆盖ActivityonCreate ,如下所示:

@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())
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();
    mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);

    setContentView(mReactRootView);
}

Note addPackage(new MainReactPackage()) . 注意addPackage(new MainReactPackage()) Regardless of which approach you use, you need to add a custom package that exposes our custom module. 无论使用哪种方法,都需要添加一个公开我们的自定义模块的自定义包。 It might look like this: 它可能看起来像这样:

class ActivityStarterReactPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new ActivityStarterModule(reactContext));
        return modules;
    }

    // UPDATE: This method was deprecated in 0.47
    // @Override
    // public List<Class<? extends JavaScriptModule>> createJSModules() {
    //     return Collections.emptyList();
    // }

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

Finally, update MainApplication to include our new package: 最后,更新MainApplication以包括我们的新软件包:

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new ActivityStarterReactPackage(), // This is it!
            new MainReactPackage()
    );
}

Or you can do addPackage(new ActivityStartecReactPackage()) to ReactInstanceManager.builder() . 或者您可以将addPackage(new ActivityStartecReactPackage())ReactInstanceManager.builder()

You can find a complete, self-contained example here . 您可以在此处找到完整的,独立的示例


UPDATE 更新

createJSModules was removed from the ReactPackage interface in version 0.47, and has been commented out of the sample. createJSModules从除去ReactPackage接口在0.47版本,和样品的已注释。 You'll still need it if you're stuck with an older version of RN for some reason. 如果由于某种原因而使用旧版本的RN,则仍然需要它。


UPDATE MARCH 2019 2019年3月更新

The sample project now supports similar functionality for iOS. 现在,示例项目为iOS支持类似的功能。

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

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