I have been using DexGuard successfully with Gradle in Android Studio without any issues. I recently tried my hands on OkBuck to speed up my build time and it really helped me.
Although it is able to build debug and signed APKs for me, but when I try building for release with DexGuard like:
./buckw install --run app:bin_release
I get the following error:
Error: Unknown option '-dalvik' in line 9 of file 'SomeApp/app/build/okbuck/release/proguard.pro',
included from line 60 of file 'buck-out/gen/app/bin_release/proguard/command-line.txt',
included from argument number 1
BUILD FAILED: //app:bin_release failed with exit code 1:
proguard_obfuscation
stderr: Error: Unknown option '-dalvik' in line 9 of file 'SomeApp/app/build/okbuck/release/proguard.pro',
included from line 60 of file 'buck-out/gen/app/bin_release/proguard/command-line.txt',
included from argument number 1
It is probably insignificant to mention the details of DexGuard integration as it is done as per the documentation and is working fine when I build from within Android Studio or using ./gradlew, but here it is:
SomeApp/build.gradle:
buildscript {
ext {
DEXGUARD_HOME = "$System.env.DEXGUARD_HOME"
}
...
SomeApp/app/build.gradle:
buildTypes {
...
release {
minifyEnabled true
proguardFile DEXGUARD_HOME + "Dexguard-7.3.11/lib/dexguard-release-aggressive.pro"
proguardFile 'dexguard-project.txt'
signingConfig signingConfigs.release
}
}
The message typically indicates that ProGuard is still enabled -- ProGuard doesn't know the DexGuard option -dalvik. You should leave minifyEnabled set to false. DexGuard itself already shrinks, optimizes, and obfuscates all code and resources.
Related
I'm running into a strange issue with gradle.
My app/build.gradle file has a section which looks like this:
buildTypes {
debug {
...
}
release {
signingConfig signingConfigs.release
...
}
beta {
initWith release
...
}
}
When I run ./gradlew assembleBeta, the output is app-beta.apk, which I can install on my device.
However, I want to change the order of my build types, purely for aesthetics. So it now looks like:
buildTypes {
debug {
...
}
beta {
initWith release
...
}
release {
signingConfig signingConfigs.release
...
}
}
This syncs fine, but when I run ./gradlew assembleBeta, the output is now app-beta-unsigned.apk! And I cannot install this apk on a device - it tells me installation failed.
How is it possible that simply by changing the order in which my build types are declared, my apk can become broken?
The reason the apk is broken after changing the order of build types is because, in this situation, gradle requires that the release build type is defined before the beta build type.
Why is this? It's because beta refers to release in the line: initWith release
If release is defined after beta, then the initWith release command will silently fail. This is because, at the point initWith release is run, release does not exist. Although it may seem like Gradle should be able to look-ahead to the definition of release later in the file, it cannot.
Then, when running ./gradlew assembleBeta, the beta apk is built successfully - but the apk is unsigned - as alluded to by the name of the output file, app-beta-unsigned.apk. In the previous setup, beta was getting its signingConfig from release. When initWith release fails, the beta build simply has no signingConfig set - so the output apk is of course unsigned.
I am trying to run my android application on other devices, it installed properly but some XML file not working properly. It works as I expected when I installed through USB debugging. I am trying to find solution for many days. I don't get anything related to my issue.
This must be the result of Obfuscation
Add this lines in your build.gradle
buildTypes {
release {
...
debuggable false
shrinkResources false
minifyEnabled false
...
}
}
or you can add your files in pro-gaurd
Debug builds work fine for me. When I choose Active Build Variant = release, and try to run Build -> Generate Bundle(s) / APK(s) -> Build APK, the build runs for a while, then I get the following error:
Unexpected attempt to get register for a value without a register in method java.util.List com.chrynan.chords.parser.AsciiChordParser.parseLineAsString(java.lang.String, int, java.util.Set).
That is referencing an external library I'm pulling in. Source code for that function is available here.
What does that error mean? My searches returned nothing remotely like it.
I solved it! I have no idea why, but I set minifyEnabled = true in my build.gradle (:app):
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
This gave me instant crashing on app start due to this problem, although I think that's unrelated. I fixed that, and now my build works.
I still have no idea why that error came up though.
For some one else having the same problem, I solved it by changing
getDefaultProguardFile( 'proguard-android-optimize.txt') to
getDefaultProguardFile( 'proguard-android.txt') in build.gradle
I would like to know how to run ProGuard from the command line.
I've built a hybrid app using Cordova with the Ionic Framework. One of the recommendations made to me was using ProGuard to obfuscate the java code and to remove the Log calls.
I'm not currently using Android Studio or Eclipse, I just have the project build out in Ionic Framework and Angular 1.X with the Cordova plugins I need for functionality on devices. I have Jenkins build my releases via command line.
I tried to follow the steps laid out here:
https://developer.android.com/studio/build/shrink-code.html#keep-code
and here:
Disable LogCat Output COMPLETELY in release Android app?
As well as combing through various questions/answers to find applicable bits.
My build.gradle is kept in ./vendor directory and copied to overwrite the autogenerated/default build.gradle from Ionic.
It has this for enabling ProGuard:
buildTypes {
debug {
debuggable true
minifyEnabled false
}
release {
signingConfig signingConfigs.release
debuggable false
minifyEnabled true
runProguard true
proguardFile 'customProGuard.txt'
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-android.txt'
}
}
I've also tried various versions of this line in my project.properties file:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt or proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
It doesn't appear to be doing anything. I thought my apk file size changed at one point, but when I look at the classes in JD-GUI I can still clearly discern things. So I don't think it's running. Any help would be appreciated.
Jenkins runs the following commands:
cp -R vendor/build.gradle platforms/android/build.gradle
ionic resources
ionic prepare android
ionic build android --release
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore $KEYSTORE platforms/android/build/outputs/apk/android-release-unsigned.apk
-keypass $KEY_PASSWORD -storepass $KEYSTORE_PASSWORD $ALIAS && \ ./zipalign -v 4 platforms/android/build/outputs/apk/android-release-unsigned.apk "build/appNameHere.apk"
While 'ionic build android --release' eventually calls ./platforms/android/cordova/lib/builders/GradleBuilder.js which has several lines referencing build.gradle, but I think the main most vital one being var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8'); in which it reads in the file to use with GradleBuilder.build:
GradleBuilder.prototype.build = function(opts) {
var wrapper = path.join(this.root, 'gradlew');
var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts);
return Q().then(function() {
return spawn(wrapper, args, {stdio: 'inherit'});
});
};
After much trial and error, the answer turned out to be that I needed this block of code to be located in a different segment of my build.gradle file.
release {
signingConfig signingConfigs.release
debuggable false
minifyEnabled true
proguardFile 'customProGuard.txt'
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-android.txt'
}
As it was, it was never being reached. By putting it in the android { } block, but not in any other functions or if statements, it consistently runs and behaves as expected.
Unfortunately, due to the way Ionic uses reflection, I'm not able to get much obfuscation use out of it (Apache Jira Bug). ProGuard can still be used to remove the console logs as per the linked article above though.
I'm having a ton of difficulty trying to get Gradle to compile a debug version of my JNI code through NDK build. I've set the debug build to be debuggable in the build.gradle file like so:
buildTypes {
debug {
debuggable true
jniDebuggable true
}
}
I can confirm that the switches are taking effect if I check out Build/Edit Build types. However, once I check the ndkBuild_build_command.txt file inside of the .externalNdkBuild directory, I notice the following entries:
NDEBUG=1
APP_PLATFORM=android-9
I can confirm that my JNI code does not seem to be debuggable. Even though the breakpoints trigger, variables all show "variable not available" in LLVM.
Any ideas as to why NDEBUG is turned on even in a debug build? As a sidenote, I also have no idea where the android-9 platform is entering in... I'm not setting that myself anywhere that I could find.
If you use Android Studio 2.2 with externalNativeBuild, you can set APP_OPTIM=debug in your Application.mk or NDK_DEBUG=1 through parameters override, e.g.
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG:=1"
}
}