I'm using Android Studio and building Android library project, so I distribute aar file. And to be more specific I just distribute the jar inside (yes- customers still using Eclipse so I combine manually the jar with manifest, res etc well known procedure).
This is my Gradle build script (regular default...):
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
buildToolsVersion "23.0.0"
lintOptions {
abortOnError false
}
defaultConfig {
// Ain't applicationIdNot
minSdkVersion 11
targetSdkVersion 22
versionCode 1
versionName "1"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/../lib'
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile '...'
}
The problem is that: Under one java package alongside regular java classes I have ttf font files. This is due to historical reasons and now the project complexity not allowing to make changes and move them to where they actually need to be.
Well - The jar missing these files. How to implement the build process such the jar inside the arr will include these files - Because after all - It's regular archive and those file are in the file tree already compressed into the jar.
Thanks,
Just specify to include the files in your sourceSets closure
// if you want to include the files in your aar
android {
...
sourceSets {
main {
resources.includes = [ '**/mySweetFont.ttf' ]
}
}
}
// to include in your jar
sourceSets {
main {
resources.includes = [ '**/mySweetFont.ttf' ]
}
}
This will place the files at the root of the artifact produced. For the jar you may need to specify the sourceSets closure twice once inside android closure and again after the android closure
Related
I am working on creating an AAR which is downloaded by the build server at compile time, it will contain a C++ pre compiled library, which will have the .so files within it. I have already got the c++ and the AAR with the respective files completed. I am not however able to consume it by my simple test application made for testing the library.
Clearly the issue is I have not told the project how to link the contents of the AAR in a way the JNI can load it. I just cant seem to find out how one is to use these AAR files for .so resources, which is a hard requirement. It is as if after it compiles with the implementation project that it is missing the /jni folder (which is clearly in its compressed contents)
I confirmed I have the .so files in the AAR with a plugin. It shows
-jni
-x86
libmyproject.so
-armeabi-v7a
libmyproject.so
in addition the other lib/res/assets etc that I do not care about.
Running my project I see the expected files in build/aar with myproject-Android-release and build/aar-debug with myproject-Android-debug.aar. Which is where I want them.
In my settings.gradle I have
include ':myproject-Android-debug',':myproject-Android-release'
In my build.gradle I have
import xxx
buildscript {
apply plugin: 'xxxx'
dependencies {
classpath brazil.tool('AndroidGradle', 'AndroidSDK', 'KotlinGradlePlugin', 'xxxx')
}
}
apply plugin: 'xxx'
apply plugin: 'xxx-android-sdk'
apply plugin: 'com.android.application'
apply plugin: 'xxx-android'
configurations {
ktlint
}
dependencies {
implementation brazil.build()
testImplementation xxx.testbuild()
ktlint brazil.tool('Ktlint')
implementation project(":myproject-Android-debug")
}
android {
compileSdkVersion SDK.platformVersion.toInteger()
buildToolsVersion SDK.buildToolsVersion
defaultConfig {
applicationId "com.company.testapp"
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
// let gradle pack the shared library into apk
//possibly here?
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
}
packagingOptions {
exclude "/META-INF/proguard/**"
}
}
task ktlint(type: JavaExec) {
inputs.files(project.fileTree(dir: "src", include: "**/*.kt"))
outputs.dir("${buildDir}/reports/ktlint/")
group = 'verification'
main = "com.github.xxxx"
classpath = configurations.ktlint
args = [
"--reporter=plain",
"--reporter=checkstyle,output=${buildDir}/reports/ktlint/ktlint-report.xml",
"src/**/*.kt"
]
}
check.dependsOn ktlint
task ktlintFormat(type: JavaExec) {
group = 'verification'
main = "xxx"
classpath = xxx
}
Crash output
2020-04-24 01:20:57.150 10387-10387/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.company.testapp, PID: 10387
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/base.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_dependencies_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_0_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_1_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_2_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_3_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_4_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_5_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_6_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_7_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_8_apk.apk", zip file "/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.company.testapp-4-XMV-9aZlJXyboIRl92bA==/lib/x86, /system/lib]]] couldn't find "libmyproject.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
at java.lang.System.loadLibrary(System.java:1669)
at com.company.project.MainActivity.<clinit>(MainActivity.kt:33)
I have a C++ library built for Android, which I package as an Android archive (.aar), along with some Java classes and a Manifest.
Everything is done outside of Android Studio. To package the .aar, I have a directory that contains:
app/src/main/jniLibs/arm64-v8a/: directory with library
app/src/main/java: directory with Java classes
The directory also contains the manifest, and Gradle files.
Here is the build.gradle in the app directory:
apply plugin: 'com.android.library'
android {
compileSdkVersion 27
buildToolsVersion "27.0.2"
defaultConfig {
minSdkVersion 21
targetSdkVersion 27
}
buildTypes {
release {
minifyEnabled false
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:27.0.2'
}
apply plugin: 'maven-publish'
publishing {
publications {
fooapp(MavenPublication) {
groupId 'com.example'
artifactId 'fooapp'
version "develop"
artifact('build/outputs/aar/app-release.aar')
}
}
repositories {
maven {
mavenLocal()
}
}
}
publishToMavenLocal.dependsOn assemble
By default, all the AAR files contain a stripped version of the library. I do not want the library to be stripped when assembling the Debug version of the AAR.
I found out that I can use packagingOptions to disable stripping, so I tried to add packagingOptions { doNotStrip "**/*/*.so" } under the debug {...} scope of the configuration file.
My problem is that both the debug and release versions of the AAR are then stripped. The two versions of the AAR do seem different, since they don't have the same size (hence have different md5sum).
Where/how can I place my packagingOptions in the Gradle configuration file so that only the release version is stripped? Thanks
The packaging options are specified under buildTypes and then the configuration like Debug or Release etc.
Example:
buildTypes {
debug {
packagingOptions {
doNotStrip '**/*.so'
}
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
packagingOptions {
doNotStrip '**/*.so'
}
}
}
Note: you added an extra directory /*/ in your specified path.
I've inherited a really messy android project with a lot of NDK dependencies and having a lot of problems with getting gradle to correctly link and include all .so and .a files into the resulting apk.
The project consists of some java code that sets up some activities and call into a big NDK library, built from C++ which in turn links with a dosens of 3rd party library (prebuilt or built from source).
I have managed to make it build with the latest gradle experimental plugin, but for some reason, my module isn't included in the apk while my 3rd party .so files are even though I can see that gradle have built my module into a .so file which it have placed in the build directory.
My build.gradle looks like this:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "22.0.1"
defaultConfig.with {
applicationId = "<removed>"
minSdkVersion.apiLevel = 7
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
ndk {
moduleName = "XM"
CFlags.add("-I${file("src/main/jni")}".toString())
cppFlags.addAll(["-I${file("../../3rd_part/android/osg")}".toString()])
cppFlags.addAll(["-I${file("../../3rd_part/android/opus")}".toString()])
ldFlags.add("-L${file("src/main/jniLibs/armeabi-v7a")}".toString())
ldLibs.addAll(["osgdb_jpeg", "osgdb_freetype", "jpeg","argsub_es", "jnigraphics", "android", "log"])
stl = "gnustl_shared"
abiFilters.add("armeabi-v7a")
}
sources {
main {
jni {
source {
srcDir "../../core"
srcDir "src/main/jni"
}
}
}
}
lintOptions.abortOnError = false
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:23.0.0'
compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:design:23.0.0'
compile 'com.wunderlist:sliding-layer:1.1.1'
}
So to sum up my question: why does gradle build my module (libXM.so), place it into build/libs/xM/shared/armeabi-v7a/debug, but not include it into my final apk file?
I didn't get several things: if you want to build a shared library with gradle, then you have to use apply plugin: 'com.android.model.library' and not application
If you want to build an application and use prebuilt library, then you have to write something like this:
sources {
main {
jni {
source {
srcDir "../../core"
srcDir "src/main/jni"
}
dependencies{
library "XM" linkage "shared"
}
And, of course, to set ldFlags previously.
How to create JAR file from Android Studio also referencing res/ folder? Below is my graddle. As of now it contains "include('classes.jar')" inside "task exportJar". Is it possible to also add resource folder?
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
useLibrary 'org.apache.http.legacy'
defaultConfig {
minSdkVersion 8
targetSdkVersion 23
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jniLibs
jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
}
//task to delete the old jar
task deleteOldJar(type: Delete){
delete 'release/AndroidPlugin.jar'
}
//task to export contents as jar
task exportJar(type: Copy){
from('build/intermediates/bundles/release/')
into('release/')
include('classes.jar')
//Give whatever name you to give
rename('classes.jar', 'Executable.jar')
}
exportJar.dependsOn(deleteOldJar, build)
To properly include resources, manifest entries, assets, in addition to compiled code, you need to create an android library which exports an AAR file (not a JAR).
You do this with an Android Library. You can create one using Android Studio with File -> New -> Module and select Android Library. You'll notice that the build.gradle it creates has apply plugin: 'com.android.library' which tells gradle that it's going to build an aar instead of an app. Other app projects can then include this aar to merge all the library resources into its own.
Android Studio 1.1 generated apk file (located # app/build/outputs/apk folder) contains the lib directory, and for every cpu type there exists a non-empty folder, like /x86. Each of these folder contain a libapp.so shared library that is around 5Kb in size per cpu.
I've searched the net and the only thing I found so far is this link from Intel https://software.intel.com/en-us/articles/building-native-android-apps-using-intelr-c-compiler-in-android-studio that shows how to change the default libapp.so to user-provided library.
So, I guess that this library (libapp.so) is somehow built by gradle.
In fact I do my own native library building, using ndk-build command line tool, and my libs are placed alongside that libapp.so. It's not causing any issues btw, but I feel that I'm losing the control over what is built and why.
Here's my humble build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
/**
* Path to *.so files
*/
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //disable automatic ndk-build
}
}
defaultConfig {
applicationId "com.sample.android"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}
How can I disable this libapp.so being built?
defaultConfig {
ndk {
moduleName "yourSelfLib"
}
}