When generating signed APKs from the Build menu I end up with the new file app/manifest-merger-release-report.txt. What is this file and should it be version controlled (like ProGuard's mapping.txt)?
That file is generated by the manifest merging step of the Android build. If you're doing a sophisticated build where multiple flavors and build types are coming into play, and especially if you're directing traffic during the merge by explicitly telling the build system how to handle specific manifest attributes, you may find the report useful.
It's not necessary to save this file, since it's only of use if you're trying to diagnose problems during the build. It's not like the Proguard mapping file, which you may need to keep so you can de-obfuscate errors and stack traces that come in from the wild.
Related
Taking inspiration from The Twelve-Factor App: V. Build, release, run, I'm working on updating our CI/CD pipeline with these three distinct steps in mind for an app being built with react-native-web.
Specifically, I want to:
Build: generate an environment agnostic artifact of the code for each platform (web, android, ios)
Release: take an artifact and a config file (API URLs, API keys, debug settings, etc), and release to each platform
This is trivial for web, which is what The Twelve-Factor App had in mind. My question is how do I read a config file on mobile platforms and how can I incorporate this with react-native-web build artifacts? Does my artifact need to contain all of the source code and dependencies so I can pull in the config at release time and build then?
Ideally, each artifact would contain code compiled for each platform that somehow knows how to pull in a config file and do something with it. Next best would be to have the source code for each platform that I can compile with a config file at release time. Third best is have a way to give each distribution enough information at release time so it can request the config at runtime.
Full disclosure, I know nothing about building and deploying mobile apps so I apologize if there is an obvious solution for this!
It's similar for Android. Once the build binary is created it's immutable.
So unfortunately that negates option #1. We can't do anything else with the binary once we build it.
I think for react-native option two is the best approach.
Essentially you'll need to build the apps at release time once you have resolved what your configs need to be. That avoids any overhead of loading stuff at runtime in option #3 and still matches nicely to Twelve Factor. You'll still have a mobile binary that matches the same configuration as your release type.
For actually reading those values, you can just drop the config file into the project's root and we can help with the setup to pull them in.
I'll be glad to discuss those details if you'd like.
UPDATE:
Anything iOS does we can do (almost as well)
Current build tools compile all code into bytecode classes.dex and compress all resrouces into resrouces.arc but res/raw is left untouched.
This gives us a place to inject our files.
From there, the app will be able to read and parse at runtime.
For iOS, the build and (non-App Store) release process works like this at a high level:
Archive your project in Xcode, which results in an .xcarchive artifact.
Export your archive which signs and generates an .ipa file.
Either host this .ipa file yourself (with some additional metadata files) or upload it to a service like HockeyApp for distribution.
There are a few ways that you can manage config inside an Xcode project. One fairly common and straightforward way is to use the info.plist file to store custom keys and values. The app can then look up and use these values at runtime.
In the scenario you describe, it sounds like you want to be able to inject specific config values after step 2 but before step 3. Fortunately, the .ipa file generated during step 2 can be extracted, which will reveal a Payload folder containing an .app file. This file can be inspected, and inside you will see, amongst other things, the app's Info.plist. Modifying this file will allow for injection of whatever config values you want to set.
This will save needing to manage configs inside the Xcode project, and creating a separate archive for each configuration of the app. However what this doesn't solve is step 3. You are still going to need to distribute each configured .ipa file separately.
In android studio's build.gradle file,we can use shrinkresources set to true to shrinkify our app.Also can use minifyenabled and proguard options as well.
But in xamarin, How can I use these options?
I use proguard in my app as it referred in xamarin doc.but didn't find any use of it (I mean my app size didn't get reduced).My simple app is having around 18Mb in size.If anyone have experience using proguard in xamarin,please paste a sample file here also explain how you accomplished this.So others can also benefited.
I know you're asking specifically about the proguard and minifyenabled features of Android Studio but if the intent is specifically to reduce the size of your application, you should configure a more aggressive linking strategy.
Right click android project
Under "Build" select "Android Build" (or "iOS Build")
Select "Link All" for "Linker behavior" dropdown
Make sure this is only for Release or Ad-Hoc configurations, depending on your distribution strategy.
Linker Configuration Workflow:
Run app on a physical device for desired configuration (Release/Ad-Hoc)
Test functionality until "TypeInitializationException" or similar exception occurs
Add the type/field/method to the configuration file
Rinse and repeat until the application is stable
If you don't like the configuration file, you can also use the PreserveAttribute. If the linker is stripping out classes in one of your PCLs that don't have access to this attribute, you can define your own attribute in that PCL called PreserverAttribute because the linker is just looking for an attribute with that name, not necessary of a specific type.
The linker works by analyzing code paths and removing what it believes to be unused references. If you use dependency injection, the linker won't understand which references it needs to keep around so this can take some time but it can drastically reduce the size of your application and you only need to do it once. You can follow the same steps above for iOS as well.
Bonus Make sure "Strip native debugging symbols" is checked in the build options. Its set by default but some disgruntled coworker could have unchecked it.
Additional Resources:
Linking on iOS
Linking on Android
Proguard only can reduce an APK size if it contains a large number of unused classes (e.g. included because of libraries). Therefore it can only reduce the size of the classes.dex file in your APK.
However an APK usually contains a large number of other files - they will not be touched by Proguard.
You should open the generated APK file in a ZIP viewer and see what elements take the space. If it is the classes.dex file it is only a matter of Proguard configuration.
My project does not enable proguard when creating it. Therefore I need to manually add proguard and enable it via project.properties.
Is there any way I can know whether my application has been obfuscated or not aside from reverse engineering?
If your application has been obfuscated you will see a new folder called proguard in you project folder.
It should contain four text files: dump, mapping, seeds and usage.
Note that your project will not be obfuscated unless you build it in release mode.
Just for records, if you want to check if your code was really obfuscated, you can generate the APK and analyse it in this webpage: http://www.javadecompilers.com/apktool
You can check using Android Studio as well by generating the APK and later going to Build -> Analyze APK... -> select your APK to analyze.
I hope this help.
I have been working on one project which is too complex and contain very much space with so many images and Java files as well.
Somewhere I have read about the proguard which optimizes the code.
I have used it, but it's still does not have an effect on my final APK file.
It might be I have made a mistake somewhere. I have the following this like http://developer.android.com/guide/developing/tools/proguard.html.
How can I optimize my code?
You can add it to the default.properties. I've been adding manually without having a problem so far.
If you add the line:
proguard.config=proguard.cfg
As said it will only use ProGuard when exporting signed application (Android Tools => Export Signed Application)
If you start the project with the SDK before Android 2.3 the proguard.cfg file will not be created (next to default.properties as in 2.3>).
To enable automatic creation of it, just simply update to the SDK of Android 2.3 and create a new project with existing sources (which are the sources of the project you currently have).
Automagically the proguard.cfg fill will be created.
Without optimizations the compiler produces very dumb code - each command is compiled in a very straightforward manner, so that it does the intended thing.
The Debug builds have optimizations disabled by default, because without the optimizations the produced executable matches the source code in a straightforward manner.
Please refer this one
From documentation:
ProGuard is integrated into the Android build system, so you do not have to invoke it manually. ProGuard runs only when you build your application in release mode, so you do not have to deal with obfuscated code when you build your application in debug mode.
I have an Android project that I recently published to the market after running it through obfuscation with ProGuard.
The project exported without any complications, but how do I know it's been obfuscated? Is there anything I could do to verify that obfuscation was successful?
Look for dump.txt, mapping.txt, seeds.txt and usage.txt. They will probably be in a proguard folder at your project directory. These are created when ProGuard is run on your code.
These are filled with information about the obfuscation, especially useful is mapping.txt which shows what ProGuard turned your various member names in to.
Try to reverse engineer your own application. See what you can read in the code.
Use the following questions:
decompiling DEX into Java sourcecode
http://www.taranfx.com/decompile-reverse-engineer-android-apk
DISCALIMER: I am not the owner of decompileandroid.com and I am not paid to promote it. I am a develper, who is satisfied with this service.
There is actually an easier way than acquiring several different tools and passing the output of one of them to the other (this of course gives you a better control of what's going on). You can use the service
decompileandroid.com
Basically you upload and .apk file and it does all of these steps for you.
Then you can download a .zip file, which contains the decompiled sources.
You can first upload your .apk built in debug mode, then upload an .apk built in release mode. Just make sure that the flag minifyEnabled is set to true in your build.gradle file for the release build.
The difference was pretty obvious in my case - most of my classes were named a,b,c, etc in the minified build.