söndag 21 juni 2015

Add native code to Android Studio project.


I felt a bit lost when switching from eclipse to the Android Studio environment. Also i found it difficult to interpret the documentations and tutorials i found online that tried to explain how to setup android studio projects. After struggling for a while i decided to learn to compile a project with the terminal first to get a grip around what was happening in the background, and then the pieces started to fall in place.

First of i added the gradle and the ndk-build to the PATH variable. The path variable is a environment variable (both in Linux and Windows) that tells the environment which programs can be executed. Here is a bit discussion that i found about it. You fix it by adding som lines in your ~/.bashrc file. This makes it possible to be able to run grandle without specifying the path on every call. I did the same for ndk-build that is located in the native sdk folder.

Create a project

If you do not already have a project select File → New → New Project... and create a project that suits for you. Alternative you can import an eclipse project by selecting File → New → Import project... Some things will differ, as i will mention in the text.

Add a jni folder to your project.

In your project explorer (probably on your left) right-click on "app" then go to New → Folder → New JNI Folder ... Select it and create a folder. Note that if you are in Android-mode (the text "android" is visible above the explorer) it might work different, but den just press the drop down menu (with the text android) and select "project".

Include library files into your project

Android studio will automatically call ndk-build in the jni-folder, so what you will have to do is to simply include your library into your code. The fastest way I found is to simply add this to your app/build.gradle

build.gradle

android {
  ... //old code
    sourceSets.main {
        jni.srcDirs = [] //This prevents the auto generation of Android.mk

        jniLibs.srcDir 'src/main/libs' //this is not necesary unless you have precompiled libraries in your project
  }
}


You could do a bit more fancy stuff to match to different types of processors, but that will do for now.

If you have imported from a eclipse project you probably have a part in your grandle script that says "ndk {... }". I use to remove this statement because otherwise grandle will complain about duplicate libraries. An other alternative is to remove the jniLibs.srcDir statement above, it seems to have a similar effect effect.

I have also noticed that when importing from an eclipse project, Android Studio puts the old files in app/jniLib/...  This caused a error message for me that confused me at first, but the solution was to simply remove the old copied so-files (the ones in app/jniLib) because new ones will be generated anyway.

Create some source files

Because the ndk-build 

Lazy way to discover function names


You need to come up with a name that reflect the native functions. However if you are a bet lazy, like me you could just run the program, without implementing the right functions and then look for a error message like this in logcat.

java.lang.UnsatisfiedLinkError: No implementation found for void se.laserskold.mattias.android1.MainActivity.test() (tried Java_se_laserskold_mattias_android1_MainActivity_test and Java_se_laserskold_mattias_android1_MainActivity_test__)

then you know what to call your function.


Here is some more good resources
http://ph0b.com/android-studio-gradle-and-ndk-integration/

Git subtree

This blogpost describes the process of setting up a git subtree with a base repositories and one ore more subrepositories. One of the benefits of using subtree instead of gitmodules is that the subtree is checked out automatically with the main repository.

First of all. Make sure to have your sub-repository initialized and ready. If you don't have one, open a terminal, go to your projects root folder and run

git init


Add your subtree project


git subtree add --prefix matgui git@github.com:mls-m5/matgui.git master --squash

where the --squash parameter makes sure that you only checkout a shallow copy of the subrepository

One thing i noticed when doing this was that you need to commit or stash all your changes before adding the subtree so that you have a clean repository to work with.


Save the repository to be able to update it later on

git remote add -f matgui git@github.com:mls-m5/matgui.git

This will add a reference to the place where you got the code from

If you want to pull down changes to your project you then just have to use

git pull -s subtree matgui master

References