Android Kotlin: Local Variables unavailable during debugging - android

Starting today I am unable to debug locally scoped variables in Kotlin using Android Studio 4.0.1 (Build number AI-193.6911.18.40.6626763). Yesterday I did not have this issue.
I'm using android gradle 4.0.1 and build gradle of 6.1.1, after having tried rolling back I've reset to those.
Example code that I cannot debug:
private fun collapse(){
val start = endIndicies[2]
val end = endIndicies[3]
...
}
My debugger has no problem with resolving object scoped members, however locally scoped variables do not resolve when stepping through the code:
I'm running a debuggable build.
I have invalidated caches and restarted.
I have cleaned and rebuilt the project.
I have tried rolling back to previous gradle versions.
I have tried adding -dontobfuscate to my proguard file.
I've deleted my build files from the app folders, then rebuilt.
My debug config in the app/build.gradle file looks like this:
debug {
debuggable true
minifyEnabled false
shrinkResources false
}
When I attempt to debug code in a library that is pulled in via gradle I have no issues debugging locally scoped variables.
app/build.gradle
dependencies{
implementation project(':com.example.core')
...
}
So I'm fairly certain it's a configuration issue with the app module, and I suspect it's some rogue R8 obfuscation issue, though I'm not sure what.

Related

Why does Android Studio want the debug version of a library in a release build?

Why does a release build complain about a missing debug library?
In order to verify that a release version of an app uses only the release components, I deleted the debug variants of some externally-built libraries, and then tried building the release version of the app. The build variant 'release" is selected, yet the build stops immediately with this error: 'Expecting a file or a directory: theLibrary-debug.aar'.
When theLibrary-debug.aar is present, the release version of the app builds fine, and shows up in its correct place. The app behaves correctly, with release variants in behavior also, so it appears that the build completes correctly, and that the debug library isn't used.
So why does the release build complain about the missing debug library? Is this a normal build behavior in Android Studio (version 4.1.1) or does this require further investigation?
With the names changed, the relevant parts of the app's build.gradle look like this:
...
android {
...
buildTypes {
release {
...
}
debug {
...
}
}
...
}
dependencies {
debugImplementation files ('theLibrary-debug.aar')
releaseImplementation files ('theLibrary-release.aar')
}
P.S. The Module Settings view in Android Studio is awful, and it only makes sense to work in the gradle files, as far as I can see. Any one of the many Eclipse IDEs out there does this sort of settings work much better. Maybe some of the more recent Android Studio versions have some improvements...

What does 'minifyEnabled=true' do when all configuration options are disabled?

I have a complicated build setup for an android app which basically consists of a normal android app fused together with a Xamarin/Mono project in order to include an important C# library (like this: https://github.com/royd/KotlinAppWithXamarinDependency)
Everything is working fine except if I enable minification in my app/build.gradle via minifyEnabled true the app instantly crashes on startup because the Mono-runtime can't find native assemblies that are definitely contained in the apk.
This is the message I get in Logcat:
A/monodroid: No assemblies found in '(null)' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...
With minifyEnabled false everything is working fine so I tried disabling all config options in my proguard-rules.pro:
-dontobfuscate
-dontoptimize
-dontshrink
And I also added the following lines to my app/build.gradle
packagingOptions {
doNotStrip "*/armeabi/*.so"
doNotStrip "*/armeabi-v7a/*.so"
doNotStrip "*/x86/*.so"
}
Unfortunately all this doesn't help.
I also decompiled a working and a broken apk with dex2jar to compare the bytecode. It seems to be exactly the same except for some enum-optimizations that shouldn't matter.
According to the error message in Logcat the error seems to be thrown from the native library libmonodroid.so.
So my question: What does minifyenabled flag do when all these config options are disabled?
Edit:
I have found out that minification works as intended when I use version 4.0.1 of Android Gradle Plugin (from July 2020). Upgrading the version to 4.1.0 (August 2020) breaks my app. Now the question is what changed between these two versions?
When you set the minifyenabled as true. The r8 will choose the configuration files but not only the proguard-rules.pro and the app/build.gradle to shrink, obfuscate, and optimize your app.
There are some others files such as AAR libraries: <library-dir>/proguard.txt and
JAR libraries: <library-dir>/META-INF/proguard/ and so on. So this error may be caused by the native library losing when you set the set the minifyenabled as true.
If you need more information, please check the official document:https://developer.android.com/studio/build/shrink-code#enable
In addition, you can check the 'proguard-android-optimize.txt' and when you add the -dontoptimize to proguard-rules.pro may cause a conflict.
I found out, that in the Android Gradle Plugin versions 3.6.0 to 4.1.0 they switched to a more performant tool for building apks called zipflinger.
This tool can be disabled by adding this line to my gradle.properties:
android.useNewApkCreator=false
When building the apk zipflinger stores the external .NET assemblies as DEFLATED zip entries instead of STORED and thats why monodroid cant read them.
References:
https://github.com/xamarin/xamarin-android/issues/6838#issuecomment-1110816027
https://copyfuture.com/blogs-details/20210119115509664T

How would you troubleshoot dependency errors that arise in Release mode only in Android?

Context
We have an Android app built in Kotlin and we've split our algorithms layer into a separate Android Project. We import that as a dependency using Gradle using the following code:
In build.gradle:
dependencies {
...
implementation project(':algos-android')
}
This algos-android project has its own dependency - koma - defined in the algos-android project's build.gradle file as follows:
dependencies {
...
implementation group: "com.kyonifer", name:"koma-core-ejml", version: "0.12"
}
Issue
This works completely fine when running the app in a debug mode (defined in buildTypes in the build.gradle). However, when running in release mode, we are seeing an error at runtime when our algorithms layer uses its sub-dependency - koma.
The following error shows up in the console:
java.lang.IllegalStateException: No double matrix factories available. (Did you forget to import a koma-core implementation?)
My team was under the assumption that Gradle handles sub-dependencies for us. Has anyone run into issues like this before? Are there any good debug approaches?
Things We've Tried
Moving all of the files from our algos-android project directly into the main project and importing koma directly in the main project's gradle.build file.
Environment
Android Studio 4.0.1
Kotlin Version 1.3.72
Gradle Version 6.3
Subdependency Repo:
https://github.com/kyonifer/koma
We were finally able to track down the issue and resolve this with the following addition to the proguard-rules.pro file:
-keep class koma.** { *; }
We were able to find that since the Matrix factory classes are inflated in koma sources using reflection, proguard considered them as unused and simply deleted them from the release build.
Note: If you see this and make this fix, don't forget to Clean Project before running.

Android Studio 2.1 debugger does not show local variables

I am trying to debug over network in Android Studio. I connected via port 5555 and generally it is possible step through break points. But it often takes minutes just to execute one line of code and the other thing is that I don't see any variables which are no members. All I see is the this object, but no variables from within methods. How can I enable it?
As you can see I am within the method and at least the activity object is initialized, but it is not visible in the variables monitor.
UPDATE:
The problem remains when using USB debugging. No local variables are visible, not even when trying to evaluate expressions while debugging:
Android Studio 2.1, Gradle 2.1.0, Java 1.8
Had the same problem.
There is a bug in Android Studio, see https://code.google.com/p/android/issues/detail?id=93730
They recommend removing in build.gradle (app), this fixed the issue for me.
android {
buildTypes {
debug {
...
testCoverageEnabled true
}
}
}
After a while of figuring out this same issue, I realized I was running a release build rather than a debug build.
The build variants window may not be open in Android Studio by default. Go to Tool Windows -> Build Variants. In the Build Variants window, select the appropriate build.
In your app.gradle file, make sure debuggable is set to true in the build variant you would like to debug:
android {
// ...
buildTypes {
release {
// ...
}
debug {
debuggable true
}
}
// ...
}
If you would like to debug your release build, go ahead and add debuggable true to your release build.
Hope this helps!
I tried setting testCoverageEnabled to false but that did not work for me. In my case, I had ProGuard enabled for my debug flavor and disabling it (i.e. setting minifiyEnabled to false) was the only thing that allowed me to be able to see my local variables while debugging again.
In my case, it was because I had forgotten that my build variant was set to release. Toggling the variant back to debug and re-running correctly showed the local variables.
For me I had to set testCoverageEnabled to false like so:
android {
buildTypes {
debug {
...
testCoverageEnabled false
}
}
}
When I had this set to true, I was not getting local variables
While this is not a permanent solution to this problem, my most consistent fix (after trying the other answers here to no avail) has simply been restarting my computer.
I tried some kind of hit n trial and made it work with the settings as seen in the attachment. FYI, using latest version of Android Studio 3.3.1 and gradle version 4.6.
I had same trouble. I completely reinstalled my IDE and the trouble has been disappeared. I hope my approach will help you.
Java 1.8 does not support accessing variable values.
Update Gradle to version 2.2.0-beta3:
In your gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
In your project build.gradle file
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0-beta3'
}

Android gradle, about those methods that are deprected after updating

I have encountered this problem several time whenever I update my Gradle version & Gradle Android plugin. For example, I used to use:
Gradle 2.1
Gradle Android Plugin com.android.tools.build:gradle:0.13.3
With this version, my build script contains for example:
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), \
'proguard.cfg'
}
debug {
runProguard false
}
}
Few weeks later, I saw a new Gradle version (2.2.1) was released, so, I updated my Gradle & Gradle Android Plugin to newer version:
Gradle 2.2.1
Gradle Android Plugin com.android.tools.build:gradle:1.0.0+
Then, I run command gradle clean build, suddenly, the build is not successful anymore, because with the newer version, I got error:
Could not find method runProguard()
My questions are:
(MAIN QUESTION) It seems everytime when the Gradle & Gradle Android Plugin are updated, there are always some methods are deprecated, it is understandable. BUT, I am really appreciate if there is a document summarizes all the deprecated methods & their replacements. So, where can I find such information? Seems Gradle & Gradle Android Plugin don't do a good job on this to facilitate developers to quickly migrate the build script to newer version.
How to get rid of the error: Could not find method runProguard() in my above case?
change
runProguard ****
to
minifyEnabled ****
you can get the deprecated methods or resources here http://tools.android.com/tech-docs/new-build-system for the android studio builds or releases
I really want to know where is the place to find out the replacements of deprecated methods in general when Gradle & Gradle Android Plugin are updated
That would be the documentation, particularly the release notes. 0.14.0 renamed runProguard to minifyEnabled, and 0.14.3 removed runProguard.
You should replace runProguard true with minifyEnabled true, there are a lot of question about this topic.
On your first question, I read some official statement here saying that, from now on, they'll try to stick to actual methods name and/or provide support info, to make the switch between gradle versions easier, so you shouldn't be worried.
From version 1.0.0 and going forward, we will strive much harder to not make incompatible changes, and if we do, we plan to write IDE support to help migrate the projects automatically.

Categories

Resources