Phonegap 2.4 Android Proguard config - android

I've upgraded a build from Phonegap (Cordova) 2.0 to 2.4 and everything was working fine in dev until I actually came to testing the final release apk. What I'm finding, after a lot of time wasted, is that for some reason now when I run the build my proguard config is breaking the phonegap build in some way that means that when it runs the deviceready is never called. There seem to be no errors when building, nor running and nothing as far as I can see but I'm guessing something is silently failing in the cordova js as i'm not getting compile / log errors on the device.
As I say this is ONLY when having ran the Proguard obfs in the build process. If i turn off Proguard it all works fine. I reverted all my code back to 2.0 to be sure and that is all fine so somewhere along the way there has been a stuble change that is seemingly not documented / or nobody has hit just yet (2.4 only came out a few weeks ago - at time of writing 26th feb 2013).
My Proguard config contains the following for phonegap (as well as some other standard config)
-keep public class * extends com.phonegap.api.Plugin
-keep public class * extends org.apache.cordova.api.Plugin
-keep public class org.apache.cordova.DroidGap
-keep public class org.apache.cordova.**
-keep public class org.apache.**
-dontwarn android.webkit.*
-dontwarn org.apache.**
and decompiling the dex doesn't seem to throw any light - everything looks ok at a glance...
Anyone have any ideas???

Try replacing the Cordova "keep" settings in your proguard-project.txt with the following line, which should maintain all Cordova classes, fields, and methods, both public and private (and thus reenable deviceready):
-keep class org.apache.cordova.** { *; }
Then you just need to include your class(es) (presumably extending CordovaPlugin, not just Plugin) e.g.
pre-v3:
-keep public class * extends org.apache.cordova.api.CordovaPlugin
v3+:
-keep public class * extends org.apache.cordova.CordovaPlugin

Phonegap Plugins are being excluded from the final APK I guess. Cordova.js probably doesn't even exist to give errors.

Related

Release build with R8 not excluding classes

I'm facing some issues when compiling the release version of my app.
I'm currently using Room and I have my model classes are under:
com.example.room.entity
and in order to let the app working I'm using a proguard rule
-keepattributes *Annotation*,SourceFile,LineNumberTable
-keep class com.example.room.entity.**.* { *; }
Once I build the version and I execute on my phone the app crash and I can see
Caused by java.lang.ClassNotFoundException
com.roommate.example.room.entity.UserEntity
The output of -printusage shows me that the the class I'm trying to preserve is somewhat touched by R8.
What can I do to enforce my rules?
Try to change second line to:
-keep class com.roommate.example.room.entity.** { *; }

Is there any proguard rules should use while using EncryptedSharedPreferences?

before using EncryptedSharedPreferences my app works fine in release mode with (minifyEnabled = true), After adding the security library (version 1.0.0-rc01) to my application the app crash while opening and if i use (minifyEnabled = false) the app works fine, i think i missing something to add it in proguard-rules.pro but i have searched a lot did not found anything.
Looks like something wrong with Tink obfuscation. My current workaround is add this rule to proguard:
-keep class com.google.crypto.tink.** { *; }
But also keep track of updates of issue here.
UPDATE - 06.01.2020
There is more effective solution (thanks #jtsalva to pointing out):
-keepclassmembers class * extends com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite {
<fields>;
}
UPDATE - 08.19.2020
This issue should now fixed in Version 1.0.0-rc03
This issue has been answered with a more targeted proguard rule here
-keepclassmembers class * extends com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite {
<fields>;
}
This saves my app ~0.2MB compared to the currently accepted answer
i try all above . not working for my case.
this what i do and work perfect:
-keepclassmembers class * extends com.google** {
<fields>; }

Finotes not reporting issues

I am using Automated bug reporting SDK finotes in android.
I had integrated the sdk and it was reporting issues during development
but I created a release build for testing. Looks like it is not reporting issues anymore.
Any help will be appreciated.
As per their documentation make sure that you add the following in your pro-guard configuration
-keep class com.finotes.android.finotescore.* { *; }
-keepclassmembers class * {
#com.finotes.android.finotescore.annotation.Observe *;
}
Also make sure that, in init() function doesn’t have their dry run turned ON
dryRun flag will prevent the issues from syncing to their dashboard.
For release build, change init() in Application class to,
Fn.init(this);

Memory leak only in release mode with Proguard

I have an Android App that works well in debug mode, but that has some kind of memory leak in release mode. Basically, it is really slow and the following line appears repeatedly in logcat:
dalvikvm D WAIT_FOR_CONCURRENT_GC blocked 91ms
If I don't obfuscate, don't shrink and don't optimize in proguard, then the release works. If I do one of them, I have this error. I use the following lines:
-dontshrink
-dontoptimize
-dontobfuscate
I am using multiple external libraries that use some native (i.e. JNI) code, and I have no idea what could be wrong.
How can I identify where the issue comes from?
Can I tell proguard to optimize/shrink/obfuscate only one package, so that I can try to isolate the problem?
You can tell Proguard to not interfere with, I mean obfuscate, packages and subpackages using instructions like this in the proguard config file:
-keep class com.google.** { *; }
-keep class okio.** { *; }
You can also tell it to keep classes annotated with a specific annotation using:
-keep class com.your.annotation
-keep #com.your.annotation class * { *; }
The first keep instruction makes sure it doesn't remove the annotation itself, and the second keeps anything annotated with it.
The full Proguard manual with other examples can be found here.

Obfuscate Android Test project as well as project (running test on release and obfuscated version)

Let's say I got an android app project with tests.
Is there any way we can run our test suite (in a separate test project) against the release version ?
After reading the bounty's comment, I realised OP actually ask something more than a simple Yes/No reply, so I am going to extend my comment to an answer. Generally speaking, a proper designed proguard.cfg and project structure is sufficient to prevent this dilemma.
A typical proguard configuration (see section 7. A complete Android application section in this link) guarantee that all android related stuff like Activity, View and etc. is preserved during obfuscation. It doesn't make any sense to alter the configuration for example, to obfuscate Acticity.onCreate() method as it will obviously ruin the application at runtime. In another word, a well design proguard.cfg will protect all public interface to the underlying runtime framework and keep them remain unchanged.
... ...
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
... ...
On the other hand, Android test project should focus on testing Android component (Intentionally preserved during obfuscation), i.e. a view is proerly rendered, a button click perform correct task, and should avoid writing tests for POJO class that doesn't rely on any Android API, note that these POJOs are what we obfuscate usually. It is better to write pure junit tests for these POJO in the application or referenced java project so that these junit tests are involved at maven test phase before creating the final release (obfuscated, signed and zipaligned). In addition, a good OO design will shield these intermediate POJO dependencies and make them transparent to the outside, i.e. the runtime framework.
app/
src/main/java/
src/test/java/ <-- intermediate POJO tests put here.
AndroidManifest.xml
... ...
app-test/
src/main/java <-- Android component tests put here.
AndroidManifest.xml
... ...
It is absolutely fine to write POJO junit tests inside Android test project, however, if you still want to keep the ability to run the test project against obfuscated apk, you need adjust application project's proguard.cfg properly and preserve the POJO class during obfuscation in order to suit the test code.
You can instruct proguard to write out the mapping it creates into a file using the -printmapping <filename> directive. The structure of that file is obvious and can be parsed into a Hashtable. Then I would write a script that does apply those conversions onto your tests (making copies of them). Obfuscation simply means replacing class and method names from something (human-readable and) valid in terms of the Java Bytecode Specification to something other (short and not human-readable but) also valid, so this should work. Compile the adapted tests against the obfuscated project and run them.
Do you have your tests and source in one project? if so I believe android maven will strip out the test code when you perform a release.
To fix this you will need to move the tests to a seperate project that links to your actual application (assuming you rely on code/assets of your actual project) then the seperate project will still be able to instrument against a release build of your app (assuming they are signed by the same key).

Categories

Resources