如何从React Native Android模块访问Activity?

我试图弥合保持屏幕到React Native的Androidfunction。 我想我可以用一个简单的模块做到这一点,但是我不知道如何从上述模块访问当前的Android活动。

我需要活动引用,所以我可以调用.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 在上面

我试图通过像这样((Activity)getReactApplicationContext().getBaseContext())铸造得到活动,但是这会抛出一个“不能转换为Android.app.Activity”错误

Solutions Collecting From Web of "如何从React Native Android模块访问Activity?"

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是我的本地用户界面组件。 我定义了一个构造函数,以便可以传入活动:

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

最后,在定义了ReactInstanceManager MainActivity.java中,我们可以将活动传递给我们的自定义React包:

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

更新反应地方0.29.0

这不再是如何访问本地模块中的活动。 有关迁移说明,请参阅https://github.com/facebook/react-native/releases/tag/v0.29.0

我猜ReactContextBaseJavaModule的 getCurrentActivity()方法可能会像下面的代码一样从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; } } } 

Editted:

问题是getReactApplicationContext()返回应用程序的上下文而不是活动。 您不能将应用程序上下文转换为活动。

这是一个简单的解决方法

通常,react-native中只有一个活动(Main Activity),我们可以在MainActivity中编写一个静态函数来返回活动

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

然后从桥模块中调用MainActivity.getActivity()

对于0.28和之前,您可以从ReactInstanceManagerImplprivate @Nullable Activity mCurrentActivity; ,0.29+的ReactContextBaseJavaModule使用相同的字段。

你如何从ReactApplication :: getPackages()传递活动到一个包?

我不明白。 我找不到任何明确的例子

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

答:您不能将活动从MainApplication传递给包。

您可以从ReactContextBaseJavaModule中调用getCurrentActivity()

我需要修改一个过时的模块( react-android-360-video ),并发现这有帮助…

android/app/src/main/java/com/webcdpmobiledemo/MainApplication.java ,我使用了新的格式来添加一个包:

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

android/app/src/main/java/com/webcdpmobiledemo/MainActivity.java基本上是空的:

 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"; } } 

然后,我修改了VrVideoViewPackage文件,它需要将reactContext传递给它所调用的VrVideoViewManager

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

最后,在VrVideoViewManager ,可以这样访问活动:

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

https://github.com/facebook/react-native/blob/master/docs/NativeModulesAndroid.md不是很清楚,但是你可以在反应原生分布中阅读ToastModule的源代码,看看它们是如何做到的github.com/facebook/react-native/blob/daba14264c9f0d29c0327440df25d81c2f58316c/ReactAndroid/src/main/java/com/facebook/react/modules/toast/ToastModule.java#L31-L33

这个想法是,主要活动将被作为reactContext在ReactInstanceManager.builder()中调用的模块的初始化程序中传递github.com/facebook/react-native/blob/3b4845f93c296ed93c348733809845d587227823/local-cli/generator-android/ templates / package / MainActivity.java#L28通过MainReactPackage实例化github.com/facebook/react-native/blob/daba14264c9f0d29c0327440df25d81c2f58316c/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java#L49