How can I set up a simple gradle project that uses sqlite4java?
For compiling your own sqlite3 libraries, you can check github android-sqlite3
For the current Android Studio (3.3.1), you can simply add the .so
files inside app/build.gradle
like below:
android {
...
sourceSets {
main {
jniLibs.srcDirs += ['<your-path>/your-libs']
}
}
...
}
Explanation
jniLibs.srcDirs
is the gradle path pointing at jni libraries, operator +=
denotes the additional jni libraries besides the default ones inside app/src/main/jniLibs
as below:
app/
├──libs/
| └── *.jar <-- java libs
├──src/
└── main/
├── AndroidManifest.xml
├── java/
└── jniLibs/ <-- default directory for jni libs, i.e. <ANDROID_ABI>/**.so
And please note that the jni libraries have to be organized according to android ABI, i.e.
your-libs/
├── arm64-v8a/ <-- ARM 64bit
│ └── lib-your-abc.so
├── armeabi-v7a/ <-- ARM 32bit
│ └── lib-your-abc.so
├── x86_64/ <-- Intel 64bit
│ └── lib-your-abc.so
└── x86/ <-- Intel 32bit
└── lib-your-abc.so
I suppose, you need to use additional gradle plugin to handle native libraries or make your own specific tasks, to upload and put native libs in right place, in order to they could be found and linked.
At the moment I know only about one such a plugin, hope it can solve your problem https://github.com/cjstehno/gradle-natives
Edit: The problem with plugin in your case is the fact, that your dependecny "com.almworks.sqlite4java:libsqlite4java-osx:1.0.392" is native lib by itself, not a jar with included native lib as I supposed. So, in that case, you can simply add this dependency in dependencies par of build script, as it'a already done, and then create a custom copy task, to put it in any place you need. Tried to do it with gradle 2.6 on Win7, look like:
task copyNtiveDeps(type: Copy) {
from (configurations.compile+configurations.testCompile) {
include "libsqlite4java-osx-1.0.392.dylib"
}
into "c:\\tmp"
}
In your case, you just need to set "into" property to some path from java.library.path. And the second, you can make this task runs automaticaly with gradle task properties dependsOn and mustRunAfter.
Here's a complete answer based on Stanislav's comments.
apply plugin: 'java'
/* We use Java 1.8 */
sourceCompatibility = 1.8
targetCompatibility = 1.8
version = '1.0'
repositories { mavenCentral() }
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile "com.almworks.sqlite4java:sqlite4java:1.0.392"
compile "com.almworks.sqlite4java:libsqlite4java-osx:1.0.392"
}
sourceSets {
main {
java.srcDir 'src'
output.classesDir = 'build/main'
}
test {
java.srcDir 'test'
output.classesDir = 'build/test'
}
}
/* Copy the native files */
task copyNativeDeps(type: Copy) {
from (configurations.compile+configurations.testCompile) {
include "*.dylib"
}
into 'build/libs'
}
/* Make sure we setup the tests to actually copy
* the native files and set the paths correctly. */
test {
dependsOn copyNativeDeps
systemProperty "java.library.path", 'build/libs'
}
And example test source to run for it:
import com.almworks.sqlite4java.SQLiteConnection;
import com.almworks.sqlite4java.SQLiteStatement;
import org.junit.Test;
import java.io.File;
public class SqliteTest {
@Test public void aTest() throws Exception {
SQLiteConnection db = new SQLiteConnection(new File("/tmp/database"));
db.open(true);
SQLiteStatement st = db.prepare("SELECT name FROM dummy");
try {
while(st.step()) {
System.err.printf("name = %s\n", st.columnString(1));
}
} finally {
st.dispose();
}
}
}