8

I have a WebView in my activity, and using Proguard for obfuscation seems to break my WebView and i don't understand why.

The code is pretty simple, I have the HTML file in my res/raw directory, here is the code that loads it fine when debugging.

WebView mv = (WebView)findViewById(R.id.webView1);
mv.loadUrl("file:///android_res/raw/wesite.html");

As soon as I create the apk for release, running it through proguard it doesn't work, i just get the cannot load page.

I haven't added anything to the proguard config file as yet.

Ne0
  • 2,688
  • 3
  • 35
  • 49

4 Answers4

11

Proguard obfuscates directories so if you are looking for android_res/raw it is probably no longer called that!

You can add rules to the proguard.cfg file in your project that will make it skip certain files. But in this case, moving your raw resource to the assets folder will do the trick.

The problem is that the Webkit FileLoader will try and load your R$drawable class using reflection. If you do not add any keep rule to your proguard.cfg file that class will be renamed, hence Webkit will not be able to load your resource. (Taken from Prevent Proguard to remove specific drawables ).

This is why Android uses the R class naming system for resources - a uniquie lookup id instead of referencing the files by their location

By placing the file into the assets folder your are bypassing the R class referencing system and everything should work okay.

You should move your website.html file into the assets folder and call:

mv.loadUrl("file:///android_asset/wesite.html");

As is suggested at the link above, it should be possible to add the below rule to your Proguard.cfg file to stop the resources location being obfucated instead:

-keepclassmembers class **.R$* {
    public static <fields>;
}

-keep class **.R$*

Bare in mind the obfuscation works the way it does for a reason!

Hope this helps

Community
  • 1
  • 1
biddulph.r
  • 5,226
  • 3
  • 32
  • 47
  • 1
    The above does work for the Proguard.cnf and moving the website to the assets folder. However the code should be, `mv.loadUrl("file:///android_asset/wesite.html");` **Note:** `android_asset` not `android_assets`. Thank you for your explanation. – Ne0 Aug 24 '12 at 15:48
  • You don't need to keep all R classes and their fields, it should be possible to cherry-pick some resource names that you really want to keep and let the rest (e.g. layout|xml|values) be obfuscated. – TWiStErRob Jun 28 '16 at 11:41
1

Just to clarify the asset vs assets debate. The folder in the project directory should be called "assets" as per google docs (see below) whereas to access them you must use "file:///android_asset/"

assets/ This is empty. You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original filename is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.

Please note that I can't add any comment, that's why I posted this as answer.

0

Just to update after having been lead to this post by a more recent question.

In Android Studio (1.0.1 at least) there is no difference in the default level of obfuscation provided in a release build if you use assets or res for your media. android_res/raw or android_asset. And they were both still called that.

I ran apktool on both builds, startled by the latest, using android_res/raw, being bigger. The size was solely caused by my media. Both were hardly obfuscated at all, in line with other apks on the app store. Resources and xml were on neither occasion obfuscated. The only difficulty one would have reverse engineering these is converting the baksmali to Java. I've seen other apk better obfuscated but mine retained the original class names I gave them, albeit broken up into several parts.

I'm new to pro-guard, preferring C++ but from I understand it is applied by default for release builds.

John
  • 6,433
  • 7
  • 47
  • 82
-1

To load a files of raw folder in a webview:

myWebView.loadUrl("file:///android_assets/myfile.html");
xagema
  • 775
  • 1
  • 7
  • 14
  • That loads files from the asset directory, not the raw directory. Please read the post. The problem is with Proguards obfuscation, not with the code. – Ne0 Aug 24 '12 at 15:30