android - 如何在启动 React Native Activity 时发送数据?

标签 android react-native

我想在启动时发送数据以响应 native Activity ,我有 RecyclerView在安卓 Activity 中MainActivity显示订单列表,点击项目我想在 reactNative Activity 中打开该订单的详细 View 。但我无法发送数据,因为我得到 ReactContextnull在每个 Activity 生命周期回调上。
启动 React Activity 如下:

    @Override
    public void onItemClick(Order order) {
    Intent intent = new Intent(MainActivity.this, ReactNativeActivity.class);
    intent.putExtra("order",order);
    startActivityForResult(intent, 9);
    }
ReactVative Activity :
public class ReactNativeActivity extends ReactActivity {

private Order order;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    order = (Order) getIntent().getSerializableExtra("order");
   
    WritableMap map = new WritableNativeMap();
    map.putBoolean("complete", order.isCompleted());
    map.putString("id", order.getId());
    //Here I am getting null reactcontext
    sendEvent(getReactInstanceManager().getCurrentReactContext(), "order", map);

}

private void sendEvent(ReactContext reactContext,
                       String eventName,
                       WritableMap params) {
    reactContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit(eventName, params);
}

public Order getOrder() {
    return order;
}


@Override
protected String getMainComponentName() {
    return "JioAssignment";
}

public void setResult(boolean isCompleted, String id) {
    Intent intent = new Intent();
    intent.putExtra("completed", isCompleted);
    intent.putExtra("id", id);
    setResult(9, intent);
    finish();
}
}
应用类:
public class MainApplication extends Application implements ReactApplication {

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

    @Override
    protected List<ReactPackage> getPackages() {
        mCustomPackage =  new CustomReactPackage();
        return Arrays.<ReactPackage>asList(
                new MainReactPackage(), mCustomPackage

        );
    }

    @Override
    protected String getJSMainModuleName() {
        return "index";
    }
};

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

public CustomReactPackage getmCustomPackage() {
    return mCustomPackage;
}

@Override
public void onCreate() {
    super.onCreate();
    SoLoader.init(this, false);
}
}
客户包:
public class CustomReactPackage implements ReactPackage {

private Bridge mBridge;
private ReactApplicationContext reactContext;

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    this.reactContext = reactContext;
    mBridge = new Bridge(reactContext);

    modules.add(mBridge);
    return modules;

}

public Bridge getmBridge() {
    return mBridge;
}

public ReactApplicationContext getReactContext() {
    return reactContext;
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
}
}
ReactContextBaseJava 模块:
public class Bridge extends ReactContextBaseJavaModule {
private Order order;

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

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

@Nullable
@Override
public Map<String, Object> getConstants() {

    Map<String, Object> vmap = new HashMap<>();
    vmap.put("completed", ((ReactNativeActivity) getCurrentActivity()).getOrder().isCompleted());
    vmap.put("id", ((ReactNativeActivity) getCurrentActivity()).getOrder().getId());
    return vmap;
}

private void sendEvent(
                       String eventName,
                       WritableMap params) {
    getReactApplicationContext()
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit(eventName, params);
}

@ReactMethod
public void updateOrder(boolean isCompleted, String id) {
    ((ReactNativeActivity) getCurrentActivity()).setResult(isCompleted, id);
    Log.w("update", id);
}


}

最佳答案

React native 接受来自承载 ReactContext 的 Activity 的 Prop 。创建一个 ReactActivityDelegate 并在你的 ReactActivity 中分配它。

public class ReactNativeActivityDelegate extends ReactActivityDelegate {
    private Bundle initialProps = null;
    private Activity activity;

    public ReactNativeActivityDelegate(Activity activity, @Nullable String mainComponentName) {
        super(activity, mainComponentName);
        this.activity = activity;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if(activity != null) {
            Bundle bundle = activity.getIntent().getExtras();
            if(bundle != null) {
                initialProps = bundle;
            }
        }
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    protected Bundle getLaunchOptions() {
        return initialProps;
    }
}
像这样在 react Activity 中分配
public class ReactNativeBaseActivity extends ReactActivity {

    @Override
    protected String getMainComponentName() {
        return ReactNativeActivityDelegate.REACT_NATIVE_COMPONENT_NAME;
    }

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactNativeActivityDelegate(this, getMainComponentName());
    }
}
像往常一样将 bundle 传递到 Activity 中。传递的包将可以在 ReactNative Prop 中访问。
这段代码在生产中,我们使用它如下所示。
String initialRoute = aOrBView() ? 
ReactNativeActivityDelegate.INITIAL_ROUTE_A_VIEW : 
ReactNativeActivityDelegate.INITIAL_ROUTE_B_VIEW;
                        
nextIntent.putExtra(ReactNativeActivityDelegate.EXTRA_INITIAL_ROUTE, initialRoute);
startActivity(nextIntent);
然后我们像这样在 ReactNative 中使用它......
let initialRouteId = this.props.initialRoute && 
this.props.initialRoute.length > 0 ? this.props.initialRoute : 'DefaultRoute'
    return (
      <Navigator ....

关于android - 如何在启动 React Native Activity 时发送数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49263165/

相关文章:

android - React Native Flipper 调试问题 : "NO APPLICATION SELECTED"

android - 如何将图像 url 转换为 Drawable Int

java - 点击时使用 ImageView 填充屏幕

android - 指定的 Firebase 路径超出了可写入的最大深度

api - React Native/Expo : Fetch throws “Network request failed”

ios - React native 应用程序在启动时在设备中崩溃。在模拟器中工作正常

android - ViewPager 中嵌套 fragment 的 OptionsMenu

javascript - setParams 不适用于回调函数

react-native - axios 出现网络错误并响应 native

react-native - 构建使用react-native构建的android应用时出错