2017-02-15 3 views
3

Ich benutze REACT-NATIVE, um Android-App zu bauen. Ich möchte Android-Aktivität von React-Native-Code anrufen. (Sagen, wenn ich auf die Schaltfläche geklickt in meinem nativen Code reagieren, sollte es android Aktivität nennen)Anruf Android-Aktivität von React-Native Code

Ich habe 4 Klassendateien

  • MainActivity.java (erstellt durch reagieren-native wenn in Android Studio geöffnet)
  • MainApplication.java (erstellt durch reagieren-native)
  • Login.java (android Aktivitätsdatei)
  • Example.java (android Aktivitätsdatei)

Möchten Sie folgenden Fluss erreichen:

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

ich bereits durch folgende Links ging, aber nicht in der Lage

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

zu verstehen ähnliche Fragen gestellt hier

React Native Android: Showing an Activity from Java

Antwort

10

Um eine Android-Aktivität zu starten, müssen Sie ein benutzerdefiniertes natives Modul erstellen. Angenommen, man nennt ActivityStarter; es könnte von JavaScript wie folgt verwendet werden:

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 nur eine Java-Klasse, die einen NativeModule genannt Reagieren native Java-Schnittstelle implementiert. Das Heben schwerer Lasten dieser Schnittstelle wird bereits von BaseJavaModule getan, so dass man normalerweise erstreckt sich entweder, dass ein oder 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); 
    } 
} 

Der Name dieser Klasse keine Rolle spielt; Der Modulname ActivityStarter, der JavaScript ausgesetzt ist, stammt aus der getName()-Methode.

Die von react-native init generierte Standard-App enthält eine MainApplication-Klasse, die Native React Native initialisiert. Unter anderem erweitert sie ReactNativeHost seiner getPackages Methode überschreiben:

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

Wenn Sie das Hinzufügen Reagieren Heimisch in eine bestehende App, this page Sie außer Kraft gesetzt hat Ihre Activity ‚s onCreate wie folgt:

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

Hinweis addPackage(new MainReactPackage()). Unabhängig davon, welchen Ansatz Sie verwenden, müssen Sie ein benutzerdefiniertes Paket hinzufügen, das unser benutzerdefiniertes Modul verfügbar macht.Es könnte wie folgt aussehen:

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

Schließlich MainApplication aktualisieren unser neues Paket enthalten:

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

Oder Sie können addPackage(new ActivityStartecReactPackage())-ReactInstanceManager.builder() tun.

Sie können eine vollständige, self-contained example here finden.


UPDATE

createJSModules wurde aus der ReactPackage Schnittstelle in der Version 0.47, entfernt und hat aus der Probe kommentiert worden. Sie werden es immer noch brauchen, wenn Sie aus irgendeinem Grund mit einer älteren Version von RN stecken bleiben.