Comment accéder à L'activité à partir D'un module Android React Native?

J'essaie de combler la fonctionnalité Android de garder l'écran allumé pour réagir natif. J'ai pensé que je pourrais le faire avec un module simple, mais je ne sais pas comment accéder à l'Activité Android actuelle à partir dudit module.

J'ai besoin de la référence D'activité pour pouvoir appeler .getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); dessus

J'ai essayé d'obtenir l'activité via le casting comme ceci ((Activity)getReactApplicationContext().getBaseContext()), mais cela lance un " Impossible à lancer sur Android.App.Activité " erreur

21
demandé sur marcshilling 2015-09-21 23:50:39

7 réponses

CustomReactPackage.java:

public class CustomReactPackage implements ReactPackage {

    private Activity mActivity = null;

    public CustomReactPackage(Activity activity) {
        mActivity = activity;
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        // Add native modules here
        return modules;
    }

    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        List<ViewManager> modules = new ArrayList<>();
        // Add native UI components here
        modules.add(new LSPlayerManager(mActivity));
        return modules;
    }
}

LSPlayerManager est mon composant D'interface utilisateur natif. Je définis un constructeur afin que je puisse passer dans l'activité:

public LSPlayerManager(Activity activity) {
    mActivity = activity;
}

Et enfin dans MainActivity.java où le ReactInstanceManager est défini, nous pouvons passer l'activité à notre paquet React personnalisé:

mReactInstanceManager = ReactInstanceManager.builder()
        .setApplication(getApplication())
        .setBundleAssetName("index.android.bundle")
        .setJSMainModuleName("src/index.android")
        .addPackage(new MainReactPackage())
        .addPackage(new CustomReactPackage(this)) // <--- LIKE THIS!
        .setUseDeveloperSupport(BuildConfig.DEBUG)
        .setInitialLifecycleState(LifecycleState.RESUMED)
        .build();

MISE À JOUR POUR REACT NATIVE 0.29.0

Ce n'est plus la façon dont vous accédez à l'activité dans un module natif. Voir https://github.com/facebook/react-native/releases/tag/v0.29.0 pour les instructions de migration

32
répondu marcshilling 2016-07-14 18:04:23

Je suppose que getCurrentActivity() Méthode de ReactContextBaseJavaModule pourrait être utilisé comme le code suivant qui a été copié à partir du code d'origine React-Native;

import android.app.Activity;
import com.facebook.react.bridge.ReactContextBaseJavaModule;

public class AwesomeModule extends ReactContextBaseJavaModule {

  public AwesomeModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

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

  private static final String ERROR_NO_ACTIVITY = "E_NO_ACTIVITY";
  private static final String ERROR_NO_ACTIVITY_MESSAGE = "Tried to do the something while not attached to an Activity";

  @ReactMethod
  public void doSomething(successCallback, errorCallback) {

    final Activity activity = getCurrentActivity();

    if (activity == null) {
      errorCallback(ERROR_NO_ACTIVITY, ERROR_NO_ACTIVITY_MESSAGE);
      return;
    }

  }

}
14
répondu efkan 2016-07-21 12:56:41

Édité:

Le problème est que getReactApplicationContext() renvoie le contexte de l'Application et non l'activité. Vous ne pouvez pas convertir un contexte D'Application en une activité.

C'est une solution de contournement simple

Comme il n'y a généralement qu'une seule activité (activité principale) dans react-native, nous pouvons écrire une fonction statique dans MainActivity pour renvoyer l'activité

private static Activity mCurrentActivity = null;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mCurrentActivity = this;
    ...
}
...
public static Activity getActivity(){
    Activity activity = new Activity();
    activity = mCurrentActivity;
    return activity;
}

Puis appelez MainActivity.getActivity() à partir des modules de Pont

3
répondu Nishanth Shankar 2015-09-24 06:29:45

Pour 0.28 et avant, vous pouvez obtenir l'activité de ReactInstanceManagerImpl s private @Nullable Activity mCurrentActivity;, 0.29 + ' s ReactContextBaseJavaModule en utilisant le même champ.

0
répondu oscarthecat 2016-08-01 11:00:34

Comment passez-vous l'activité à un paquet à partir de ReactApplication:: getPackages ()?

Je ne comprends pas. Je ne trouve aucun exemple clair

package com.bluetoothioexample;

import android.app.Application;
import android.util.Log;

import com.facebook.react.bridge.ReactContextBaseJavaModule;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;

import java.util.Arrays;
import java.util.List;

import com.subsite.bluetoothio.BluetoothIOPackage;
import com.oblador.vectoricons.VectorIconsPackage;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    protected boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new BluetoothIOPackage(this), //<- How pass the activity
                                        // from ReactApplication ?
          new VectorIconsPackage()
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
      return mReactNativeHost;
  }
}

Réponse: vous ne passez pas L'activité de MainApplication au paquet.

Vous appelez getCurrentActivity () depuis votre ReactContextBaseJavaModule

0
répondu Ed of the Mountain 2016-08-12 17:34:28

Ce n'est pas super clair de https://github.com/facebook/react-native/blob/master/docs/NativeModulesAndroid.md , mais vous pouvez lire le code source du ToastModule dans la distribution native react pour voir comment ils le font github.com/facebook/react-native/blob/daba14264c9f0d29c0327440df25d81c2f58316c/ReactAndroid/src/main/java/com/facebook/react/modules/toast/ToastModule.java#L31-L33

L'idée est que l'activité principale sera passée en tant que reactContext dans l'initialiseur pour le module appelé à partir de ReactInstanceManager.builder () appeler github.com/facebook/react-native/blob/3b4845f93c296ed93c348733809845d587227823/local-cli/generator-android/templates/package/MainActivity.java#L28 via l'instanciation de MainReactPackage github.com/facebook/react-native/blob/daba14264c9f0d29c0327440df25d81c2f58316c/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java#L49

-1
répondu Jérôme Cornet 2015-09-22 01:12:15

J'avais besoin de modifier un module obsolète ( react-android-360-video) et j'ai trouvé cela utile...

Dans android/app/src/main/java/com/webcdpmobiledemo/MainApplication.java, j'ai utilisé le nouveau format pour ajouter un paquet:

...
import com.vrvideocomponent.VrVideoViewPackage;

public class MainApplication extends Application implements ReactApplication {

    ...

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
      ...

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

      ...
    };

    ...
}

Et {[5] } sont essentiellement vides:

package com.yourproject;

import com.facebook.react.ReactActivity;

public class MainActivity extends ReactActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "YourProject";
    }
}

Ensuite, j'ai modifié le fichier VrVideoViewPackage, qui doit passer le reactContext au VrVideoViewManager qu'il appelle:

...

public class VrVideoViewPackage implements ReactPackage {
    ...

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Arrays.<ViewManager>asList(
                new VrVideoViewManager(reactContext)
        );
    }

}

Et enfin, dans le VrVideoViewManager l'activité est accessible comme ceci:

...

import android.app.Activity;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.bridge.ReactContext;

...

public class VrVideoViewManager extends SimpleViewManager<VrVideoView> {
    ...

    public VrVideoViewManager(ReactContext reactContext) {
        // Do not store mActivity, always getCurrentActivity when needed
        Activity mActivity = mContext.getCurrentActivity();
    }

    @Override
    protected VrVideoView createViewInstance(ThemedReactContext reactContext) {

        // You can also activity from ThemedReactContext
        Activity mActivity = reactContext.getCurrentActivity();

        VrVideoView vrView = new VrVideoView(mActivity);
        vrView.setEventListener(new ActivityEventListener(vrView));
        vrView.pauseVideo();
        return new VrVideoView(mActivity);
    }

    ...
}
-1
répondu David Sinclair 2017-06-26 18:55:02