Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Android WebView not displaying bundled assets #17304

Conversation

jeanregisser
Copy link
Contributor

@jeanregisser jeanregisser commented Dec 21, 2017

Motivation

On Android, when using WebView with source={require('./page.html')} it displays a blank page on release builds (or when bundleInDebug: true is set under project.ext.react in android/app/build.gradle).

The bug is not present on iOS (debug and release) or on Android in debug mode.

The bug was reported several times:

The reason it happens is because on release builds, the native ReactWebView loads the uri of the bundled asset, which in this case is just the resource name:

{ 
  __packager_asset: true,
  width: undefined,
  height: undefined,
  uri: 'page',
  scale: 1
}

The fix I'm proposing resolves the resource name to get a valid url which can be loaded successfully by the ReactWebView.

I've also investigated a fix for this on the JS side but it would require augmenting the resolveAssetSource method so it works for any type of asset for the WebView (html, svg, png, etc) and still remains compatible when resolveAssetSource is used within the Image component.

Let me know what you think.

Test Plan

  • Setup new React Native project: react-native init WebViewTest
  • Create page.html
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>
  • Modify App.js
import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  WebView,
  View
} from 'react-native';

export default class WebViewTest extends Component {
  render() {
    return (
      <View style={styles.container}>
        <WebView
          scalesPageToFit={true}
          source={require('./page.html')}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});
  • Build Release APK
  • Run On Android
  • Hello World should be displayed

Related PRs

N/A

Release Notes

[ANDROID] [BUGFIX] [WebView] - Make source={require('./page.html')} work in release mode

This was seen in release builds see the following issues:
facebook#16133
facebook#7924
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Dec 21, 2017
@jeanregisser jeanregisser changed the title Fix Android WebView not displaying bundled resources Fix Android WebView not displaying bundled assets Dec 21, 2017
@facebook-github-bot
Copy link
Contributor

@jeanregisser I tried to find reviewers for this pull request and wanted to ping them to take another look. However, based on the blame information for the files in this pull request I couldn't find any reviewers. This sometimes happens when the files in the pull request are new or don't exist on master anymore. Is this pull request still relevant? If yes could you please rebase? In case you know who has context on this code feel free to mention them in a comment (one person is fine). Thanks for reading and hope you will continue contributing to the project.

@jeanregisser
Copy link
Contributor Author

@mkonicek @astreet @grabbou who would be best to review these changes?
Thanks

@grabbou grabbou requested a review from shergin February 5, 2018 14:15
@grabbou
Copy link
Contributor

grabbou commented Feb 5, 2018 via email

@jeanregisser
Copy link
Contributor Author

Yep I checked the diff and @mkonicek appeared at the top of the list (because he opensourced the initial Android version), all other contributions were from external contributors.

@asowayan
Copy link

@janicduplessis any chance you can review this PR?

@brancooo1

This comment has been minimized.

@react-native-bot react-native-bot added Android Ran Commands One of our bots successfully processed a command. Component: WebView Related to the WebView component. labels Mar 14, 2018
@react-native-bot react-native-bot added Platform: Android Android applications. Ran Commands One of our bots successfully processed a command. labels Mar 18, 2018
@lucaslz2020

This comment has been minimized.

@jeanregisser
Copy link
Contributor Author

@hramos could you help in getting this reviewed/merged?
Thanks

@yosimasu
Copy link

yosimasu commented Aug 4, 2018

@jeanregisser
I try to build android from source(0.55-stable) with your patch.
I deploy a release android app to try, I got a blank page.

e.g.

<WebView
    scalesPageToFit={true}
    source={require('./page.html')}
/>

The url will be file:///android_res/raw/page.

I try to another solution: read input stream to string, and loadData with the string.
Here is my code.

  if (source.hasKey("uri")) {
        Context context = view.getContext();
        int id = context.getResources().getIdentifier(
          source.getString("uri"),
          "raw",
          context.getPackageName()
        );
        if (id > 0) {
          view.loadData(readTextFromResource(context, id), HTML_MIME_TYPE, HTML_ENCODING);
          return;
        }
       ...
  }
  ...
  protected String readTextFromResource(Context context, int resourceID)
  {
  	InputStream raw = context.getResources().openRawResource(resourceID);
  	ByteArrayOutputStream stream = new ByteArrayOutputStream();
  	int i;
  	try
  	{
  		i = raw.read();
  		while (i != -1)
  		{
  			stream.write(i);
  			i = raw.read();
  		}
  		raw.close();
  	}
  	catch (IOException e)
  	{
  		e.printStackTrace();
  	}
  	return stream.toString();
  }

It works.

After I try, I think the scenario require('./page.html') between ios and android is different.

  1. Android: it need a bundled html, contains everything it need, such as css, image, js, ...etc.
  2. iOS: It will keep directory structure, like functionality of android assets folder.

Only the bundled html can keep the same situation on both platform.

@hramos
Copy link
Contributor

hramos commented Aug 9, 2018

WebView PRs are on hold pending approval of the WebView proposal at react-native-community/discussions-and-proposals#3

@jamonholmgren
Copy link
Collaborator

@hramos
Copy link
Contributor

hramos commented Sep 26, 2018

Closing in favor of submitting to the new repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Component: WebView Related to the WebView component. Platform: Android Android applications. Ran Commands One of our bots successfully processed a command.
Projects
None yet
Development

Successfully merging this pull request may close these issues.