Skip to content

fix: support file asset loading on android#389

Merged
mfazekas merged 2 commits intorive-app:mainfrom
mfazekas:mfazekas/pr329-improvements
Nov 6, 2025
Merged

fix: support file asset loading on android#389
mfazekas merged 2 commits intorive-app:mainfrom
mfazekas:mfazekas/pr329-improvements

Conversation

@mfazekas
Copy link
Copy Markdown
Collaborator

@mfazekas mfazekas commented Nov 5, 2025

Based on PR#329 with a simpler implementation

Add support for file:// URLs on android

Closes #329

@mfazekas mfazekas marked this pull request as ready for review November 5, 2025 19:16
@mfazekas mfazekas changed the title refactor: simplify file:// URL loading with URI.scheme checking fix: support file asset loading on android Nov 6, 2025
@mfazekas mfazekas requested a review from HayesGordon November 6, 2025 05:17
ckknight and others added 2 commits November 6, 2025 11:38
This updates the definition of `RiveReactNativeView.downloadUrlAsset` to load `file://` URLs via `java.io.File`

Formerly, if a `file://` URL was loaded, that would lead to `com.android.volley.VolleyError: java.lang.ClassCastException: sun.net.www.protocol.file.FileURLConnection cannot be cast to java.net.HttpURLConnection`

This only affects Android apps built in release mode, as debug mode is unaffected.
Simplify PR rive-app#329 implementation by removing unnecessary factory pattern
and using iOS-style approach with simple conditional dispatch.

Changes:
- Remove ResourceLoaderFactory, ResourceLoader interface, and implementations
- Replace factory pattern with simple if/else using URI.scheme
- Add loadFileUrlAsset() with background threading (Dispatchers.IO)
- Add loadRemoteUrlAsset() wrapping existing Volley logic
- Use proper URI parsing instead of string.startsWith()

Benefits:
- 50 fewer lines of code (net: -14 lines)
- Matches iOS architectural pattern (simple conditional dispatch)
- More maintainable - no unnecessary abstractions
- Uses URI.scheme for robust URL checking vs string matching
- Keeps critical improvements: background threading and error handling

Threading improvements:
- File I/O on Dispatchers.IO background thread
- Callbacks on main thread with withContext(Dispatchers.Main)
- Matches iOS pattern (DispatchQueue.global + DispatchQueue.main.async)

Error handling improvements:
- Check file existence and permissions before reading
- Return 404 NetworkResponse for FileNotFoundException
- Clear error messages for different failure modes

URL parsing improvements:
- Use java.net.URI instead of string.substring()
- Handles edge cases: file://, file:///, URL encoding
- Validates URI syntax properly
- Case-insensitive scheme checking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@mfazekas mfazekas force-pushed the mfazekas/pr329-improvements branch from 9944a3b to 090f582 Compare November 6, 2025 10:38
Copy link
Copy Markdown
Contributor

@HayesGordon HayesGordon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@mfazekas mfazekas merged commit 274f0b6 into rive-app:main Nov 6, 2025
github-merge-queue bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Nov 12, 2025
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
In this PR: 
- I enabled EAS updates for internal users. That's is all envs except
for production and dev. However, with check automatically set to false,
the users will not receive updates.
- Fix Rive Animation issues on Android and iOS based on the PRs below
iOS: rive-app/rive-react-native#344
Android:  rive-app/rive-react-native#389
 



Builds:
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/fd79ecf5-0141-4a3f-91ab-cd9681648fe4
## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:Enabled EAS updates for preview channel

## **Related issues**

Fixes:Rive animation with EAS updates introduced

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enables EAS updates on the preview channel (no auto-check), surfaces
OTA details in App Information, and patches Rive to load file:// assets
on iOS/Android.
> 
> - **OTA Updates**:
> - Enable EAS Updates for `preview` channel with `runtimeVersion`,
`updateUrl`, and `checkAutomatically: NEVER` via
`scripts/update-expo-channel.js` (updates Android `meta-data` and iOS
`Expo.plist`).
>   - Add `UPDATE_URL` export in `app/constants/ota.ts`.
> - **Settings UI**:
> - App Information view now displays `Expo Project ID`, `Update ID`,
`channel`, `runtimeVersion`, `OTA Update URL`, `Check Automatically`,
and status when revealed.
>   - Tests added to verify OTA info visibility and values.
> - `expo-updates` mock extended with `url`, `checkAutomatically`, and
resolved async methods.
> - **Rive Animation (patch)**:
> - Android: replace Volley-only path with `ResourceLoader` factory
supporting `file://` (direct FS) and HTTP (Volley).
> - iOS: split URL asset loading into file vs remote handlers; relax URL
validation to allow file URLs.
>   - Apply Yarn patch to `rive-react-native@9.3.4` in `package.json`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7b1d329. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
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.

3 participants