如何在ReactContextBaseJavaModule中实现onPictureInPictureModeChanged回调
React Native原生模块实现画中画模式变更监听方案
不能直接在ReactContextBaseJavaModule子类中覆写onPictureInPictureModeChanged方法实现对应逻辑,该回调是AppCompatActivity的生命周期方法,原生模块默认不持有该事件的监听能力,你可以通过以下方案实现需求:
实现步骤
原生模块注册Activity生命周期监听
在你的ReactNativeBitmovinPlayerModule中注册Activity生命周期监听器,持有当前活跃的AppCompatActivity实例,避免后续操作空指针:
public class ReactNativeBitmovinPlayerModule extends ReactContextBaseJavaModule { private PlayerView playerView; private AppCompatActivity currentActivity; public ReactNativeBitmovinPlayerModule(ReactApplicationContext reactContext) { super(reactContext); // 注册Activity生命周期监听 reactContext.addActivityLifecycleEventListener(new ActivityLifecycleEventListener() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { if (activity instanceof AppCompatActivity) { currentActivity = (AppCompatActivity) activity; } } @Override public void onActivityStarted(Activity activity) {} @Override public void onActivityResumed(Activity activity) {} @Override public void onActivityPaused(Activity activity) {} @Override public void onActivityStopped(Activity activity) {} @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} @Override public void onActivityDestroyed(Activity activity) { if (currentActivity == activity) { currentActivity = null; } } }); } // 其余原有代码保留 }
宿主Activity转发画中画状态变更事件
只有承载播放器的Activity能收到onPictureInPictureModeChanged回调,你需要在Activity的对应回调中把事件转发给原生模块:
@Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) { super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); // 拿到原生模块实例转发事件 ReactInstanceManager reactInstanceManager = getReactNativeHost().getReactInstanceManager(); ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); if (reactContext != null) { ReactNativeBitmovinPlayerModule playerModule = reactContext.getNativeModule(ReactNativeBitmovinPlayerModule.class); if (playerModule != null) { playerModule.handlePictureInPictureModeChanged(isInPictureInPictureMode, newConfig); } } }
原生模块实现画中画状态处理逻辑
在原生模块中新增公开的状态处理方法,写入你需要实现的业务逻辑,也可以根据需要把状态同步给JS层:
public void handlePictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) { if (currentActivity == null || playerView == null) { return; } // 原有业务逻辑 if (isInPictureInPictureMode) { currentActivity.getSupportActionBar().hide(); } else { currentActivity.getSupportActionBar().show(); } playerView.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig); // 可选:同步状态到JS层 WritableMap params = Arguments.createMap(); params.putBoolean("isActive", isInPictureInPictureMode); getReactApplicationContext() .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("pipModeChanged", params); }
注意事项
- 所有操作前都要对
currentActivity、playerView等实例做空校验,避免空指针崩溃 - 需在
AndroidManifest.xml中给对应Activity添加android:supportsPictureInPicture="true"配置,声明支持画中画能力 - 画中画功能仅支持Android 8.0(API level 26)及以上系统版本,低版本系统要做兼容降级处理
内容的提问来源于stack exchange,提问作者Jonathan Machado
相关产品推荐
相关产品推荐

