web-dev-qa-db-fra.com

Appelez Android à partir du code React-Native

J'utilise REACT-NATIVE pour créer Android. Je veux appeler Android à partir du code React-Native. (Par exemple, lorsque j'ai cliqué sur le bouton dans mon réagir au code natif, il doit appeler Android)

J'ai 4 fichiers de classe

  • MainActivity.Java (créé par react-native lorsqu'il est ouvert dans Android studio)
  • MainApplication.Java (créé par react-native)
  • Login.Java (fichier d'activité Android)
  • Example.Java (fichier d'activité Android)

Vous souhaitez atteindre le flux suivant:

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

J'ai déjà parcouru les liens suivants, mais je ne comprends pas

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

Question similaire posée ici

React Native Android: Affichage d'une activité depuis Java

13
Ritesh

Pour démarrer une activité Android Android, vous devez créer un module natif personnalisé. Supposez-en un appelé ActivityStarter; il peut être utilisé à partir de JavaScript comme suit:

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 est juste une classe Java qui implémente une React Native Java interface appelée NativeModule. Le gros du travail de cette interface est déjà fait par BaseJavaModule, donc on étend normalement celle-là ou 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);
    }
}

Le nom de cette classe n'a pas d'importance; le nom du module ActivityStarter exposé à JavaScript provient de la méthode getName().

L'application par défaut générée par react-native init Contient une classe MainApplication qui initialise React Native. Entre autres, elle étend ReactNativeHost pour remplacer son getPackages méthode:

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

Si vous ajoutez React Native à une application existante, cette page vous oblige à remplacer votre Activity's onCreate comme suit:

@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);
}

Remarque addPackage(new MainReactPackage()). Quelle que soit l'approche que vous utilisez, vous devez ajouter un package personnalisé qui expose notre module personnalisé. Cela pourrait ressembler à ceci:

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

Enfin, mettez à jour MainApplication pour inclure notre nouveau package:

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

Ou vous pouvez faire addPackage(new ActivityStartecReactPackage()) à ReactInstanceManager.builder().

Vous pouvez trouver un exemple complet et autonome ici .


[~ # ~] mise à jour [~ # ~]

createJSModules a été supprimé de l'interface ReactPackage dans la version 0.47 et a été mis en commentaire dans l'exemple. Vous en aurez toujours besoin si vous êtes coincé avec une ancienne version de RN pour une raison quelconque.


MISE À JOUR MARS 2019

L'exemple de projet prend désormais en charge des fonctionnalités similaires pour iOS.

33
Petter Hesselberg