Search Unity

Use Proguard with Unity

Discussion in 'Android' started by Orion_78, Apr 14, 2015.

  1. Orion_78

    Orion_78

    Joined:
    Feb 13, 2014
    Posts:
    66
    Hi,

    I am looking to strip/reduce my APK size. I read that Proguard could do that by removing useless code and by shrinking some Jar libraries.

    Do you know how to use Proguard within Unity ?

    I read some post like http://forum.unity3d.com/threads/how-to-use-proguard-in-unity.165393/ but no answer founded yet.

    Thank you.

    Ps : I already compressed textures.
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    I never tried it myself, but AFAIK, Unity doesn't let you hook into the build process - it runs all the Android toolchain for you in order to create an APK so you cannot run ProGuard in the middle (ProGuard runs at the code level, not on an APK).

    The other option would be to generate an Android project, and then you could patch in a build script to add ProGuard to that. Not sure what would be the effects on build size, but there may be other, better options to cut the build size...
     
  3. Orion_78

    Orion_78

    Joined:
    Feb 13, 2014
    Posts:
    66
    Thanks Liortal

    I export an empty Unity project and compile it with Android Studio using Proguard (by the way, I needed to update Proguard because it doesn't support Java 1.8). It works, and the apk has been reduced by 10kb using Proguard (wohou)

    BUT I cannot figure how to compile an Unity Android Google Project with depedencies (like Facebook plugins or even play-services only). Each time I receive multiple error.

    Here is what I do:

    - export the Unity project (a ones with google play-service_lib)
    - open Android Studio, click on Import project (Eclipse ADT, Gradle, etc.)
    - select the repository where I build the Android Project
    - Click on Create project from existing sources, then next next next... finish
    - (by the way, Android Studio ask if I want to migrate the project to Gradle)

    I can make and build and even install the project, but when I start it, it begins and crash at the first scene.
    Logcat say : AndroidJavaException: java.lang.ClassNotFoundException: com.google.android.gms.ads.AdRequest$Builder

    (And yes, it works if I build directly from Unity)

    I could not event build a more complex project with facebook plugins and other stuff. When I build, it says:
    Error : Android Packager: [appliname] java.util.zip.ZipException: duplicate entry: AndroidManifest.xml
    (I try to google it, but no solution founded)

    Do you know what I am doing wrong ? Maybe in the import process ?
     
  4. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    Never tried to export a Google Android project, so no idea.

    I would assume that Unity generates this project and then compiles it for you to produce an APK, so this option should just give the intermediate output, but I may be wrong on this.
     
  5. Orion_78

    Orion_78

    Joined:
    Feb 13, 2014
    Posts:
    66
    I did it !!!

    Export Android Google Project with Unity,
    Then import my project and their library into Eclipse with ADT Android
    Then I had to manually link all missing libraries (pain in my ****)
    Then I had to remove in some .jar stuff like Android manifest and some icons which was detected as Duplicated by compilator. (simply open them with 7zip and manually remove)

    now, next step : using Proguard within Eclipse !
     
    alpha_nexus likes this.
  6. Orion_78

    Orion_78

    Joined:
    Feb 13, 2014
    Posts:
    66
    Ok, to use proguard within Unity it was simple:
    Add a line in under project.properties:

    proguard.config=[patchToAndroidSDK\]\tools\\proguard\\proguard-android-optimize.txt

    Results:
    A build using Facebook and Google Play Services plugins weight
    47 Mo using Unity or Eclipse
    45.2 Mo using Proguard
    I think Proguard is doing his job with Facebook which is the only not offusqued library

    Thanks for your help liortal !
     
    Last edited: Apr 20, 2015
  7. yathishgk

    yathishgk

    Joined:
    Sep 30, 2014
    Posts:
    5
    where i can find project.properties ??
     
  8. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    you have to create one yourself at the root of the Android project i think.
     
  9. HeaDiii

    HeaDiii

    Joined:
    May 18, 2015
    Posts:
    61
    I just don't get it to work.

    Did someone managed to get ProGuard to work with a Unity Android export?
    I tried to use Proguard directly onto the export, and i tried to import it first into Android Studio and run ProGuard over the imported project. Both times, i get like 100 Warning about how proguard wasn't able to find classes or access stuff.

    Does someone how to do this or if there are any other ways to obfuscate my code? More important, are there other ways to reduce the filesize of APKs??

    The Huge builds Unity creates is (in my opinion) the most annoying thing of the engine.
     
  10. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    By the way - Unity 5.5 beta has the option to export a gradle project, with ProGuard support.
     
  11. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @HeaDiii you have to deal with the proguard output and fix it o_O
     
  12. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    @Yury-Habets It would be great if you can point on how to use the proguard in Unity. I see proguard.txt files are getting ignored if kept with in the android libraries and also there is one more option in Minify - Gradle(Experimental) along with Proguard.

    Can any one from Unity give detailed instructions on where to place our proguard details?
    Thanks,
    VB Team
     
    Qbit86 likes this.
  13. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    Starting with Unity 2017.1 (i think), you can specify to use a proguard file under player settings. How to configure this file is a black art of its own... I don't think it has anything to do with Unity though. it's really up to your project and the libraries you use.
     
    Voxel-Busters likes this.
  14. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @liortal correct - this is the main proguard file for the project.

    Speaking of libraries - you should be able to have your own proguard file, and your own build.gradle which has a reference to your proguard file. (haven't tried that but it should work IMO)
     
  15. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    @Yury-Habets we are using a custom gradle file with a custom proguard file.

    Note that starting with Unity 2017.1, you can specify to use a proguard file under Player settings which may lead to inconsistent results. For example:

    Player Settings -> Custom proguard file is enabled (creates it under Assets/Plugins/Android/proguard-user.txt)
    Custom gradle file specifies a proguard file with a different name (for example - proguard-unity.txt)
     
  16. Appxplore

    Appxplore

    Joined:
    Oct 2, 2015
    Posts:
    26
    if you are using Unity3d 5.6.3f1 onwards, you may use the proguard-user.txt file together with the mainTemplate.gradle to proceed with Proguard.
     
    zhao5359228 likes this.
  17. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    So we need to keep the gradle file and refer the proguard? I was thinking it will by default consider proguard.txt file.

    Let me try that.
     
  18. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    We tried this but found setting proguard to off in the plugin's build.gradle is not considered. Can you please confirm the behaviour?
     
  19. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Qbit86 likes this.
  20. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @liortal what is used in this case? What do you expect it to use?
    If you are using a custom build.gradle - then the player settings won't be applied - my assumption.
     
  21. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    Thanks @Yury-Habets for the pointers.
    Let me have a try by adding that new attribute in build.gradle and see if its considering the settings.
     
  22. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    yes you are right, that's how it works. kind of confusing though.
     
  23. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Agree this is confusing. Will see if we can fix that.
     
  24. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    BTW what are the new "Minify" options and what do they mean? how do they relate to my custom gradle and custom proguard files ?
     
  25. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    @Yury-Habets Apologies for not getting back. Got bit busy past weeks.

    I tried the solution your referenced and it worked well. Good that publishers don't need to mess up with the main gradle file.

    I have few questions to make it better. In the gradle I used i need to mention the build tools version and compilation SDK version. Any way we can get it replaced with a macro (as this restricts to have the build tools installed if I leave it hardcoded)


    Code (CSharp):
    1. buildscript {
    2.     repositories {
    3.             jcenter()
    4.             mavenLocal()
    5.     }
    6.     dependencies {
    7.         classpath 'com.android.tools.build:gradle:2.3.3'
    8.     }
    9. }
    10.  
    11. apply plugin: 'com.android.library'
    12.  
    13. dependencies {
    14.     compile fileTree(dir: 'bin', include: ['*.jar'])
    15.     compile fileTree(dir: 'libs', include: ['*.jar'])
    16. }
    17.  
    18. android {
    19.     sourceSets {
    20.         main {
    21.             manifest.srcFile 'AndroidManifest.xml'
    22.             //java.srcDirs = ['src']
    23.             res.srcDirs = ['res']
    24.             assets.srcDirs = ['assets']
    25.             jniLibs.srcDirs = ['libs']
    26.         }
    27.     }
    28.  
    29.     compileSdkVersion 26
    30.     buildToolsVersion '26.0.1'
    31.     defaultConfig {
    32.         targetSdkVersion 26
    33.     }
    34.  
    35.     lintOptions {
    36.         abortOnError false
    37.     }
    38.  
    39.     buildTypes {
    40.         release {
    41.                             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.txt'
    42.                             consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.txt'
    43.         }
    44.  
    45.  
    46.  
    47.     }
    48. }
    49.  
    Please suggest.

    Thanks,
    VB Team
     
  26. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    We have BUILDTOOLS and APIVERSION for this purpose. Should work starting at least 5.6.

    Edit: right you're talking of a library... If you provide your own build.gradle, we don't do variable replacement. If you think it makes sense - submit a bug report or a suggestion on https://feedback.unity3d.com/ and try to make up some votes :)

    But why don't you want to specify your own values? You should define the buildtools version and the compile API which works with your plugins... I don't think relying on Unity configuration here is a good idea.
     
  27. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    Yes, we feel so as we don't want to hard code a version. At-least if we know what build tools are being exported it would be of great help.


    The reason was to minimise the issues. If we use our own version for build tools,compilation sdk developers who are using our plugin needs to download thise specific versions again. For ex: if we keep 25 build tools and developer needs to download that version again.
    And, its the case with one plugin.Developer can include many such plugins and he needs to keep downloading all those hardcoded versions, which is bad :(

    Hope it makes sense.

    Thanks,
    VB Team
     
  28. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    It does but you also don't want to guarantee your library builds on every build-tools version in the world.
     
    Voxel-Busters likes this.