Android React Native集成Google Pay PayButton异常问题求助
问题背景
在React Native 0.73.2应用中集成Google Pay API的原生PayButton,编写了如下Android桥接代码:
public class GooglePayButtonManager extends SimpleViewManager<PayButton> { public static final String REACT_CLASS = "GooglePayButton"; ReactApplicationContext mCallerContext; public GooglePayButtonManager(ReactApplicationContext reactContext) { mCallerContext = reactContext; } @Override public String getName() { return REACT_CLASS; } private int theme = ButtonConstants.ButtonTheme.DARK; private int type = ButtonConstants.ButtonType.BUY; private int cornerRadius = 20; @Override protected PayButton createViewInstance(@NonNull ThemedReactContext themedReactContext) { PayButton button = new PayButton(themedReactContext); button.setOnClickListener(v -> { WritableMap map = Arguments.createMap(); themedReactContext.getJSModule(RCTEventEmitter.class).receiveEvent(v.getId(), "onPress", map); }); buildButton(button); return button; } private void buildButton(PayButton button) { button.initialize(ButtonOptions.newBuilder() .setButtonTheme(theme) .setButtonType(type) .setCornerRadius(cornerRadius) .setAllowedPaymentMethods("[]") .build()); } }
使用的Google Pay Gradle包版本为19.2.1。
问题现象
- 应用首次启动时,按钮正常显示并可交互;后续启动时,按钮仅显示几秒后变为不可见,但仍能响应点击事件。重装应用可恢复,重启后问题复现。
- 调用
PayButton.initialize()时,Logcat报错:View class android.support.v7.widget.AppCompatTextView is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant).,但应用主题已配置为AppCompat子类,返回AppCompatTextView而非PayButton时无此错误。 - 修正
allowedPaymentMethods为合法配置后,按钮不再消失,但原本应显示卡号的位置为空,Logcat无相关错误。 - 按钮显示为空时,修改React Native端组件的style属性(如width从100%改为101%)并重新打包,按钮可正常显示卡号,但无法在不重新打包的情况下恢复正常显示。
排查与解决方案
1. 修复主题上下文传递问题
PayButton内部可能未正确继承当前应用的AppCompat主题,显式传入主题包装的上下文初始化按钮:
@Override protected PayButton createViewInstance(@NonNull ThemedReactContext themedReactContext) { // 用应用的AppCompat主题包装上下文 Context themedContext = new ContextThemeWrapper(themedReactContext, R.style.AppTheme); PayButton button = new PayButton(themedContext); button.setOnClickListener(v -> { WritableMap map = Arguments.createMap(); themedReactContext.getJSModule(RCTEventEmitter.class).receiveEvent(v.getId(), "onPress", map); }); buildButton(button); return button; }
确保R.style.AppTheme是项目中已配置的AppCompat主题。
2. 配置合法的allowedPaymentMethods
之前传入的空数组"[]"不符合Google Pay规范,需传入符合要求的JSON字符串。以卡支付为例:
private void buildButton(PayButton button) { String allowedPaymentMethods = "{" + "\"type\": \"CARD\"," + "\"parameters\": {" + "\"allowedAuthMethods\": [\"PAN_ONLY\", \"CRYPTOGRAM_3DS\"]," + "\"allowedCardNetworks\": [\"AMEX\", \"DISCOVER\", \"MASTERCARD\", \"VISA\"]" + "}," + "\"tokenizationSpecification\": {" + "\"type\": \"PAYMENT_GATEWAY\"," + "\"parameters\": {" + "\"gateway\": \"your-gateway-id\"," + "\"gatewayMerchantId\": \"your-merchant-id\"" + "}" + "}" + "}"; button.initialize(ButtonOptions.newBuilder() .setButtonTheme(theme) .setButtonType(type) .setCornerRadius(cornerRadius) .setAllowedPaymentMethods(allowedPaymentMethods) .build()); }
替换your-gateway-id和your-merchant-id为实际业务参数,若使用直接令牌化方案,需调整对应的配置内容。
3. 强制按钮重绘解决布局延迟
根据修改style触发重绘可恢复显示的现象,在按钮初始化后手动触发布局更新和重绘:
@Override protected PayButton createViewInstance(@NonNull ThemedReactContext themedReactContext) { Context themedContext = new ContextThemeWrapper(themedReactContext, R.style.AppTheme); PayButton button = new PayButton(themedContext); button.setOnClickListener(v -> { WritableMap map = Arguments.createMap(); themedReactContext.getJSModule(RCTEventEmitter.class).receiveEvent(v.getId(), "onPress", map); }); buildButton(button); // 延迟触发重绘,确保视图已挂载完成 button.post(() -> { button.requestLayout(); button.invalidate(); }); return button; }
4. 适配React Native视图生命周期
将PayButton的初始化逻辑移到视图挂载完成后的生命周期方法中,避免因视图未完全渲染导致的显示问题:
private boolean isButtonInitialized = false; @Override public void onAfterUpdateTransaction(@NonNull PayButton view) { super.onAfterUpdateTransaction(view); if (!isButtonInitialized) { buildButton(view); view.post(() -> { view.requestLayout(); view.invalidate(); }); isButtonInitialized = true; } }
5. 测试Google Pay SDK版本兼容性
部分高版本Google Pay SDK可能与React Native 0.73存在兼容性问题,尝试降级SDK版本,修改app/build.gradle:
implementation 'com.google.android.gms:play-services-wallet:19.0.0'
内容的提问来源于stack exchange,提问作者ausavi
相关产品推荐
相关产品推荐

