How to enable multi-dex option for Android in Unity3D? - android

On building with Unity, I am getting an error:
trouble writing output: Too many method references: 78849; max is 65536.
You may try using --multi-dex option.
But I can't figure out how to explicitly tell Unity to use multi dex.

For activation multidex on Unity follow a 3 simple steps:
1) Use Gradle build system:
Unity -> File -> Build Settings -> Build System -> Gradle.
2) Check in "Сustom Gradle Template":
Player Setting... -> Publish Settings -> Check in "Сustom Gradle Template"
3) Change mainTemplate.gradle file:
Open file from path: Assets\Plugins\Android\mainTemplate.gradle
Add folow code:
android
{
...
defaultConfig
{
multiDexEnabled true
...
}
}
Additional information:
https://docs.unity3d.com/Manual/android-gradle-overview.html

I'd suggest to check official Unity3D forum regarding this question:
Multidex Support on Android
And Q/A's from there: Too many method references when I export android build
Here's reply from Unity's official:
So the biggest reason we have not added support for this in Unity is because it doesn't work. Or rather it usually creates more problems than it solves. Unless you are targeting only modern versions of Android I would suggest you do everything in your power including stripping and proguarding your code before you take the route of multi-dex.
If you don't believe me just checkout the known limitations of the multi-dex library at Googles developer page:
https://developer.android.com/tools/building/multidex.html#limitations
So conclusion is to do all best to shrink number of methods to stay within 65K limit. For example, if you use google-play-services.jar, you can replace it with only required submodules of it.
There's also discussion around exporting to Android Studio and build the project there but, apparently, it didn't work out due to dex issue.
Also, I advocate to read this write-up regarding DEX issue.
I hope, it helps. Good luck!

Related

Android studio is slow in gradle building

Android studio is getting slow in grade building process.I noticed this problem after updating to new version 3.5.Is there any ways to
speed up the building process?
1- Make sure you’re using the latest version of Gradle. Generally with every new update there is a significant improvement in performance.
Note: Java 1.8 is faster than 1.6. Make sure it’s updated too.
2- Try to minimize the use of modules. There are many cases where we need to fork the library to modify it to fit according to our needs. A module takes 4x greater time than a jar or aar dependency. This happens due to the fact that the module needs to be built from the scratch every time.
3- Enable gradle Offline Work from Preferences-> Build, Execution, Deployment-> Build Tools-> Gradle. This will not allow the gradle to access the network during build and force it to resolve the dependencies from the cache itself.
Note: This only works if all the dependencies are downloaded and
stored in the cache once. If you need to modify or add a new
dependency you’ll have to disable this option else the build would
fail.
4-Open up the gradle.properties file from the root of your project. Add the following lines of code in it.
org.gradle.daemon=true
Gradle daemon is a background process. Adding this would consume some extra memory while building.
org.gradle.parallel=true
The above line of code enables compilation of multiple modules at the same time. Besides that it also gives us other benefits such as;
Re-using the configuration for unchanged projects
Project-level is up-to-date checks
Using pre-built artifacts in the place of building dependent projects
Adding the following line of code also aids us in speeding up the build.
org.gradle.configureondemand=true
Another important property is;
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
The above line is used to allow Java compilers to have available memory up to 2 GB (2048 MB). It should only be used if you have available memory more than 2 GB.
This is how the gradle.properties file should look like:
5- Avoid dynamic dependencies such as
compile 'com.google.maps.android:android-maps-utils:0.4+'.
Dynamic Dependencies slow down your build since they keep searching for the latest builds every time. To improve the performance we need to fix the version in place.
6- Use only those dependencies that you need. For example google maps dependency, instead of importing , like :
implementation 'com.google.android.gms:play-services:17.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
Gradle build speed depends on a lot of factors including the specification of your machine as well as your build type and android studio settings. You can check out this article on how to reduce your build time or go through the steps in the Android developer website.
Personal experience:
When I faced this issue, enabling offline mode drastically reduced my build time. The only problem is that I have to toggle this setting (on and off) every time I want to add a new dependency and this almost made me go berserk on several occasions. However, if properly handled, this helps a great deal.
I hope this helps. Merry coding!
you can set file->setting->search 'Gradle'-> check 'use local gradle distribution' and check 'offline work'.. in android studio. it will improve gradel building time.
Note: In newer version of Android studio, View->Tool Windows->Gradle->Toggle button of online/offline

How do I use the standalone Jetifier to migrate to AndroidX?

The Jetifier tool is used as part of the AndroidX migration tool bundled with Android Studio. There is an issue with the tool, however, that is outlined here: https://issuetracker.google.com/issues/113224601.
The error message looks like this when running the Jetifier on certain libraries (one particular library keeps popping up for multiple users: org.eclipse.jdt.core):
Failed to transform '/path/to/library/org.eclipse.jdt.core-3.10.0.jar' using Jetifier.
Reason: The type does not support '.' as package separator!
This issue has been fixed for a while in the Jetifier tool itself, but the fixed version has not been included in any Android Studio updates yet (even the latest canary build).
I can confirm that running the standalone Jetifier works in transforming the problematic libraries, but I have no idea how to get these transformed libraries into our project. Off the top of my head, I can think of two different ways to get this migration to AndroidX to work:
Run the standalone tool on each library and instruct Gradle to use those versions (I might need to tell the Gradle tasks not to run the Jetifier on them)
Instruct the Gradle tasks to use the standalone tool in place of the one shipped with Android Studio.
Any help getting either of the above suggested fixes to work would be greatly appreciated (or if there is another way, I'd love to know about it). The internals of the Android Gradle build system are incredibly complicated, and I really need some gurus' assistance to get past this roadblock.
This is a serious road block for us since we want to begin the process of migrating our app in parallel with our development. There are a lot of things we need to iron out with this migration, and being ready to "flip the switch" when the tool is finally updated would help keep our releases on track.
Thanks!
Actually, from that same thread that I linked, there's a workaround:
Sorry jetifier beta01 was not binary compatible with alpha10.
Please try:
buildscript {
dependencies {
classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'
}
}
So, I guess now you can specify the newest version of the Jetifier in your buildscript.
I really should have scrolled all the way to the bottom of that thread before posting this, but now hopefully this workaround is more visible to people.
UPDATE
It seems this workaround does not work with DataBinding enabled. It looks like the new Jetifier tool is trying to run on the old version:
Failed to transform '/path/to/library/jetifier-core-1.0.0-alpha10.jar'
using Jetifier. Reason: The given artifact contains a string literal
with a package reference 'android/support/v4' that cannot be safely
rewritten. Libraries using reflection such as annotation processors
need to be updated manually to add support for androidx.
UPDATE 2 (20 Nov 2018):
There is a workaround to the issue of Jetifier trying to Jetify itself being released in AGP 3.3.0-rc01 and 3.4.0-alpha04. The devs are adding the ability to blacklist libraries from being Jetified. In your gradle.properties file, add a comma-separated list of Regular Expressions to match what files you don't want the Jetifier to touch. For example:
android.jetifier.blacklist = doNot.*\\.jar
Would exclude /path/to/doNotJetify.jar
I´m a bite late to the party, but I think there is only one fast option to solve that issue:
Go to Google Archives, Agree save and terms and download Android Studio 3.3 Beta 2 - this is the latest version before the problem occurs. You also have to downgrade your build.gradle to
classpath 'com.android.tools.build:gradle:3.3.0-beta02'
using gradle-4.10.2-all should be no problem.
Perhaps the problem will be fixed with the next beta or canary release, but for now this was the only option that worked out for me.

Resolve deprecated NDK warnings in Android Studio

I have an Android app that uses OpenCV's Java wrapper for image processing. To add OpenCV to the project, I had to add the following line to gradle.properties:
android.useDeprecatedNdk=true
This had been working fine without any warnings or errors (that I know of) up until I updated my Android Studio and Gradle after a long time (I'm using Gradle 2.2.2 and Android Studio 2.2.2 now). Now when I build my app, I get the following warnings on the messages window:
Warning:Native C/C++ source code is found, but it seems that NDK
option is not configured. Note that if you have an Android.mk, it is
not used for compilation. The recommended workaround is to remove the
default jni source code directory by adding:
Warning:Deprecated NDK integration enabled by useDeprecatedNdk flag in
gradle.properties will be removed from Android Gradle plugin soon.
Even though the build is successful at this time, as the second warning informs, this is highly likely to cause some trouble in the future, so I want to resolve them as soon as possible before things go sideways.
Does anyone know how to get resolve these warnings? Or are there any other way to import OpenCV to an Android project, other than adding all the compiled code (the .so files) and setting the flag I mentioned earlier? Any help on this will be appreciated.
I would suggest to migrate over to using the native support with cmake. You could check the link which provides a step-by-step tutorial to add OpenCV using cmake via the following link.
You're code should stay the same without any changes, only necessary action is to figure out how to include them within the build process using CMakeLists.txt.
In the project pane, right click your app (in my React Native project it's the "app" catalog), and select "Link C++ project with gradle".
Now you must find the Android.mk file - it should be already generated in your_app/app/build/intermediates/ndk/debug/

Eclipse to Android Studio Import

I am moving all my source codes to AS as suggested by Android official website. However, the experience is not very good. It is very sluggish as described here. But this is not my ultimate problem for now.
I have resolved many problems such as updating the compileSdkVersion to 23 so that 99 errors of this kind:
Error:(13) Error retrieving parent for item: No resource found that matches the given name 'android:TextAppearance.Material.Inverse'.
could be rectified. But the problems keep on shooting up as I go. Now I have this 64k Dex issue.
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
I never had this Dex issue while using Eclipse. The source code I have in AS is exactly the same as when it was in Eclipse. The only differences are those gradle changes needed only to work on AS. Any idea why this sudden Dex issue? if I set multiDexEnabled to true, what are the implications?
First of all, make sure you rebuild project, after importing (Build - Clean, Builde - Rebuild Probject). Fixing this issue with limitation methods reference:
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
And also update you Application.class in java to support MultiDex. See full information here!
UPDATE:
This options ignore on Eclipse, because methods references limit can be calculated from environment (like AS in our case). Why this options doesn't include in Gradle build - still question...
Android application (APK) files contain executable bytecode files in the form of Dalvik Executable (DEX) files, which contain the compiled code used to run your app. The Dalvik Executable specification limits the total number of methods that can be referenced within a single DEX file to 65,536—including Android framework methods, library methods, and methods in your own code. In the context of computer science, the term Kilo, K, denotes 1024 (or 2^10). Because 65,536 is equal to 64 X 1024, this limit is referred to as the '64K reference limit'.
Source AS Doc
I suspect your dex error is a result of the growth of a library, but without more info, this is hard to debug. The newest version of Android Studio (2.2) provides an APK analyzer tool that makes the dex limit more transparent.
When using Google Play services APIs you should double check to make sure that you're only including the ones used with these directives
compile 'com.google.android.gms:play-services-fitness:9.6.1'
rather than including everything (full list).
If you need all the libraries you're already depending on then, this is typically resolved by enabling multidex in your development environment (requiring development using a device or emulator with L or greater), but then using minificationEnabled in your release builds such that multidex isn't required in your release APK. This results in a combination of fast debug builds and non-multidex your release builds to prevent slow startup times for your release build.
A bit more info:
When you use native multidex in debug builds (requires minSdk set to L or greater) it results in faster incremental builds because modules and libraries deploy as separate dex files and less processing between deploys.
When you use minificationEnabled in your release build it often eliminates the need for the second dex file because methods from your dependendencies that you don't use are trimmed. This typically results in a single dex nullifying the negative effects of multidex (copying the N+1 dex files on app initialization for < version L devices).
Multidex issue occurs when you use lots of libraries in your project. If your app's code have more than 64k methods then it happens.
When your application and the libraries it references reach a certain
size, you encounter build errors that indicate your app has reached a
limit of the Android app build architecture.
You can refer some links like :
How to enable multidexing with the new Android Multidex support library
http://www.rapidvaluesolutions.com/tech_blog/multidex-issue-or-building-application-over-65k-methods/
https://mutualmobile.com/posts/dex-64k-limit-not-problem-anymore-almost

Enforcing coding style and being warning and lint-free across teams in Android Studio or git/github

I'd like to set up our project in a way that ensure that coding style and being warning and lint-free is enforced for checkins. I'd also like to make it super easy for developers to see when they're not in compliance.
Ideally this would be presented from within Android Studio (all our devs are using the same IDE) when you edit a file or run a build. Additionally, it would be nice to have this enforcement "just work" when a developer clones the repo, rather than requiring any additional manual setup.
What's the cleanest way to do this?
Static code analysers like Checkstyle, FindBugs and PMD may help you.
They can be configured to use with Gradle and Android Studio with help of these scripts. If somethings wrong according to analysers' configs build will fail.
As these scrips are integrated with Gradle, thay can be commited to repo and will work when developer clones it.
Unfortunately generated reports are not integrated with Android Studio, so better way to build and run checks from console using gradle wrapper. Static analysers' tasks are configured to depend on check task, so ./gradlew check command will run them all.
Reports are located in $project.buildDir/reports directory, but it can be changed as well.
Checkstyle configurations are very flexible. They can be configured to any code style you prefer. For example, Google Java Code Checkstyle config.
PMD has ruleset to run checks over your code. It also has android rules. Here is a guide how to make a ruleset configuration for PMD.
FindBugs helps you find common bugs in Java code. E.g. it detects multiple strings concatenation using + and suggests to use StringBuilder. It can be configured with filter files.
Also do not turn off lint check entirely like this:
lintOptions {
abortOnError false
}
A better way is to disable specific checks if you don't like them, e.g.:
lintOptions {
disable 'InvalidPackage'
}

Categories

Resources