I have create .aar file from another project and added to new project.I have seen Classes are there but method name has changed.If i trying to access any method i have add in that class, got no method by that name. Finally I have seen method are like this.
public static void a(Context var0) {
if(var0 != null) {
var0.startService(new Intent(var0, TrackLocationOfficial.class));
}
}
method name has changed to a(), b(),c().
what to do?
is local .aar is working ?
It seems like your .aar was minified with proguard, this causes the methods to be renamed.
In the gradle file of your module you have enabled proguard, just disable that by
minifyEnabled false
You have to do it in your different configurations as in build and release separately
Related
What I'm trying to achieve
I'm trying to generate my REST API client for Android using OpenAPI Generator from the build.gradle script. That way, I wouldn't have to run the generator command line every time the specs change. Ideally, this would be generated when I build/assemble my app, and the sources would end up in the java (generated) folder, where generated sources are then accessible from the code (this is what happens with the BuildConfig.java file for example).
What I've tried so far
Following this link from their official GitHub, here's the build.gradle file I ended up with:
apply plugin: 'com.android.application'
apply plugin: 'org.openapi.generator'
...
openApiValidate {
inputSpec = "$rootDir/app/src/main/openapi/my-api.yaml"
recommend = true
}
openApiGenerate {
generatorName = "java"
inputSpec = "$rootDir/app/src/main/openapi/my-api.yaml"
outputDir = "$buildDir/generated/openapi"
groupId = "$project.group"
id = "$project.name-openapi"
version = "$project.version"
apiPackage = "com.example.mypackage.api"
invokerPackage = "com.example.mypackage.invoker"
modelPackage = "com.example.mypackage.model"
configOptions = [
java8 : "true",
dateLibrary : "java8",
library : "retrofit2"
]
}
...
First, I've never managed to get the API generated with the build/assemble task, even when I tried adding:
compileJava.dependsOn tasks.openApiGenerate
or
assemble.dependsOn tasks.openApiGenerate
The only way I could generate the sources was by manually triggering the openApiGenerate task:
Then, when I do generate my sources this way, they end up in the build folder but aren't accessible from my code, and aren't visible in the java (generated) folder:
I then have to manually copy/paste the generated source files to my project sources in order to use the API.
Even though I'm able to work around these issues by adding manual procedures, it would be way more maintainable if the whole process was simply automatic. I was able to achieve a similar result with another tool, Protobuf. Indeed, my gradle task gets triggered every time I build the app, and the sources end up in the java (generated) folder, so I don't have to do any additional work. The task is much simpler though, so I assume the main work that I'm not able to replicate with OpenAPI Generator is handled by the Protobuf plugin itself.
You have to specify path to the generated sources as a custom source set for your Gradle module, which is app in this case, as described here – https://developer.android.com/studio/build/build-variants#configure-sourcesets. That way Gradle will treat your sources as accessible from your code.
Something like this:
android {
...
sourceSets {
main {
java.srcDirs = ['build/generated/openapi/src/main/java']
}
}
...
}
I solved the issue you described like this, I'm using gradle.kts however.
See my build.gradle.kts
plugins {
// Your other plugins
id("org.openapi.generator") version "5.3.0"
}
openApiGenerate {
generatorName.set("kotlin")
inputSpec.set("$rootDir/app/src/main/openapi/my-api.yaml")
outputDir.set("$buildDir/generated/api")
// Your other specification
}
application {
// Your other code
sourceSets {
main {
java {
// TODO: Set this path according to what was generated for you
srcDir("$buildDir/generated/api/src/main/kotlin")
}
}
}
}
tasks.compileKotlin {
dependsOn(tasks.openApiGenerate)
}
You need to build the application at least once for the IDE to detect the library (at least this is the case for me in Intellij)
Your build should automatically generate the open api classes , to refer the generated classes in your java project you should add the generated class path to your source directory like it was mentioned in the other answers
https://developer.android.com/studio/build/build-variants#configure-sourcesets
As far as the task dependency goes , in android tasks are generated after configuration thus for gradle to recognize the task , wrap it inside afterEvaluate block like
afterEvaluate {
tasks.compileDebugJavaWithJavac.dependsOn(tasks.openApiGenerate)
}
I had this issue, and this answer https://stackoverflow.com/a/55646891/14111809 led me to a more informative error:
error: incompatible types: Object cannot be converted to Annotation
#java.lang.Object()
Taking a look at the generated files that were causing this error, noticed:
import com.squareup.moshi.Json;
After including a Moshi in the app build.gradle, the build succeeded and the generated code was accessible.
implementation("com.squareup.moshi:moshi-kotlin:1.13.0")
It is possible to set a variable in debug or release of buildTypes of app module. This doc has explained how to do that, Android: Managing different server URL for development and release.
However, my problem is different slightly. I have Project_A which is dependency to my App_Module. A class on my Project_A needs to know this build is Debug or Release. I created a variable in buildTypes based on what above doc's said (in App_Module). However, the variable seems is not visible to this dependency (Project_A).
I have following code in a class of Project_A:
if (BuildConfig.DEBUG)
{
MyConstants.URL_BASE = "https://my.debug.com";
}
else
{
MyConstants.URL_BASE = "https://my.release.com";
}
When I check the package of BuildConfig, the package belongs to Project_A (and there is no sign of App_Module in dropdown list of auto import packages). So what is your recommendation? How can I check build variant from dependency?
I used following solution for my problem. I defined Debug variable in Application class of Project_A:
// Placeholder for the BuildConfig.DEBUG flag. Should be overwritten by the final application class
// with the correct value based on build variant (debug/release).
public static boolean DEBUG = true;
Then, I'm set it from Application class of App_Module.
// Setup the debug flag
PassengerLibApplication.DEBUG = BuildConfig.DEBUG;
Therefore, my above code will be changed to
if (Project_A_Application.DEBUG)
{
MyConstants.URL_BASE = "https://my.debug.com";
}
else
{
MyConstants.URL_BASE = "https://my.release.com";
}
Can I configure fabric.io / Crashlytics to not put any code/data into one of my build flavours?
It seems that even if I disable it like so :
productFlavors {
internal {
ext.enableCrashlytics = true
}
external {
ext.enableCrashlytics = false
}
}
... fabric still adds some data into the build. If I look at classes.dex, and search for the word "fabric", I find stuff that's not there if I remove fabric from the build altogether.
( FYI: I use a wrapper class in the build flavor source directories (which is called from the Application's onCreate) to not have any code dependency on fabric in the "external" build. ==> There's no reference from my code to anything fabric in the "external" flavor. )
I use gradle to build app. And I add a suffix to the packageName of my debug version. Just as following:
buildTypes {
debug {
packageNameSuffix ".debug"
}
}
However, one of the libs I use can't work with this.
I think the lib uses code like this to get the R class:
drawable = Class.forName(this.context.getPackageName() + ".R$drawable");
And it throws java.lang.IllegalArgumentException: ResClass is not initialized.
The correct package for R is com.xxx.R$drawable. Since I add a suffix to the package, when the lib want to get the class using reflection it gets com.xxx.debug.R$drawable.
Is there any way to fix it? BTW I can't modify the code of the lib because it is a jar file.
Not sure if it can help you, I have seen a similar problem in different circumstances.
The R class is just a class, for example, when the R package name is different from the current app package name, import com.xxx.yyy.R helps.
Probably you can create a missing class as an ancestor of the class with the correct package name. This, of course, will break your non-debug build, so you will have to add this class for debug builds and remove it for non-debug ones.
I'm converting my app to use gradle, and I'm trying to use the buildTypes. I have a Constants class which I wish to modify for my release build. So I have a file at src/main/java/my/package/name/Constants.java and at src/release/java/my/package/name/Constants.java.
When I try to build this, gradle tells me the build failed on the Constants file in my release buildtype, with the error that it's a duplicate class.
I also tried adding a different sourceSet for this in my build.gradle like this:
sourceSets {
main {
java.srcDirs = ['src/main/java'];
//...
}
release {
java.srcDirs = ['src/release/java'];
}
}
But this still gives me the same error. So I'm wondering, what am I doing wrong here?
You can not have a class in main and release. You need to split it into something like debug and release.
gradle will merge the source sets for each buildType with main.
This is the reason, why the class gets duplicated in your release build.
So the rule is: put a class into main, or in every buildType but not both.
The answer from "fix" helped me on the way, but I got an error from the main Gradle, saying a constant was missing (in my class Config). This since I had my class only in paid and free version and not in main. Could not find the Config class.
Im not sure if this is a bug in Studio... I finally solved it with the following:
buildTypes {
release {
...
buildConfig "public static final boolean XYZ = false;"
}
}
And the instead of using my Config.XYZ class constant I used buildConfig.XYZ