Skip to content

Conversation

@ryaa
Copy link
Member

@ryaa ryaa commented Feb 11, 2026

Problem

When toBack=true, the plugin forwards WebView touch events to the native camera container to support pinch-to-zoom.
Previously, the WebView OnTouchListener was installed during startCamera(), before the CameraActivity fragment view was created.

Because FragmentTransaction.commit() is asynchronous, there is a short window where:

  • fragment != null (fragment instance created)
  • fragment.toBack == true (option applied)
  • fragment.frameContainerLayout == null (initialized later in CameraActivity.onCreateView())

If the user tapped during that window, the touch-forwarding path called:

fragment.frameContainerLayout.dispatchTouchEvent(event);

…and crashed with:

NullPointerException: Attempt to invoke virtual method 'boolean android.widget.FrameLayout.dispatchTouchEvent(...)' on a null object reference

Changes

This PR eliminates the race and adds defense-in-depth:

1) Install touch-forwarding only after the camera/fragment is ready

  • Removed setupBroadcast() call from startCamera().
  • Added setupBroadcast() in onCameraStarted() (before resolving the saved start call), ensuring the fragment view hierarchy exists and frameContainerLayout is initialized.

2) Add a null guard in the touch-forwarding path

Touch forwarding now checks:

  • fragment != null
  • fragment.toBack == true
  • fragment.frameContainerLayout != null

If not ready, touch events are simply not forwarded (no crash).

3) Remove the WebView touch listener on stop

  • stop() now clears the WebView touch listener via:
    • getBridge().getWebView().setOnTouchListener(null);

This prevents stale listeners from persisting across stop/start cycles or teardown.

Why this works

The listener is now installed only after CameraActivity has reached a state where its view is created and the camera preview is started, removing the timing window that previously allowed frameContainerLayout to be null.

Manual test checklist

  • toBack=true: call startCamera() and tap immediately/repeatedly while the preview is launching → no crash
  • toBack=true: once preview is visible, pinch-to-zoom still works
  • Call stopCamera() and tap afterward → no crash, listener removed
  • Repeat start → stop → start multiple times → stable, no listener leaks/crashes

ryaa added 2 commits February 11, 2026 09:39
…id.widget.FrameLayout.dispatchTouchEvent(android.view.MotionEvent)' on a null object reference capacitor-community#274
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant