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

mar*_*ing 27 android react-native

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

我需要Activity引用,所以我可以调用.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

我尝试通过像这样的方式获取活动((Activity)getReactApplicationContext().getBaseContext()),但是这会抛出"无法转换为Android.app.Activity"错误

mar*_*ing 35

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

LSPlayerManager是我的原生UI组件.我定义了一个构造函数,以便我可以传入活动:

public LSPlayerManager(Activity activity) {
    mActivity = activity;
}
Run Code Online (Sandbox Code Playgroud)

最后在MainActivity.java了哪里ReactInstanceManager定义,我们可以通过活动,我们的定制阵营包:

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();
Run Code Online (Sandbox Code Playgroud)

更新REACT NATIVE 0.29.0

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

  • @SudoPlz你是对的.现在你可以扩展`ReactContextBaseJavaModule`并调用`getCurrentActivity()`.但是,这仅适用于Native Modules,而不适用于Native UI Components.我还没有找到一种方法来获取`SimpleViewManager`类中的活动... (7认同)

efk*_*kan 19

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

  }

}
Run Code Online (Sandbox Code Playgroud)


Nis*_*kar 7

编辑:

问题是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;
}
Run Code Online (Sandbox Code Playgroud)

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