Advanced Android Getting Started
Advanced Android Getting Started
Advanced Android Getting Started
ANDROID SDK
Advanced Android:
Getting Started with the
NDK
by Shane Conder & Lauren Darcey 11 Aug 2010 67 Comments
5 1 2
Learn how to install the Android NDK and begin using it. By the end of this tutorial,
you will have created your own project that makes a simple call from Java code to
native C code.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Prerequisite Experience
Before we get started, we need to take a moment here to discuss the level of this
tutorial. Its flagged as advanced. The reason for this is that we, the authors, are
going to assume that you would agree with the following statements:
If you arent comfortable with these, youre welcome to read this tutorial, of course,
but you may have difficulties at certain steps that would be resolved by being
comfortable with the above. That said, using the NDK is still a process that is prone
to problems and issues even if you consider yourself a mobile development
veteran. Be aware that you may have to do some troubleshooting of your own
before you get everything working smoothly on your development system.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
The complete sample project for this tutorial can be downloaded open source code.
Generally speaking, you only need to use the NDK if your application is truly
processor bound. That is, you have algorithms that are using all of the processor
within the DalvikVM and would benefit from running natively. Also, dont forget that
in Android 2.2, a JIT compiler will improve the performance of such code as well.
Another reason to use the NDK is for ease of porting. If youve got loads of C code
for your existing application, using the NDK could speed up your projects
development process as well as help keep changes synchronized between your
Android and non-Android projects. This can be particularly true of OpenGL ES
applications written for other platforms.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Dont assume youll increase your applications performance just because youre
using native code. The Java<->Native C exchanges add some overhead, so its
only really worthwhile if youve got some intensive processing to do.
Download the NDK for your operating system from the Android site.
If any of these versions are too old, please update them before continuing.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Step 1: Installing the NDK
Now that the NDK is downloaded (it is, right?), you need to unzip it. Do so and
place it in an appropriate directory. We put ours in the same directory that we put
the Android SDK. Remember where you put it.
At this point, you may want to add the NDK tools to your path. If youre on Mac or
Linux, you can do this with your native path setting. If youre on Windows using
Cygwin, you need to configure the Cygwin path setting.
At the top level of this project, create a directory called jni this is where youll put
your native code. If youre familiar with JNI, the Android NDK is heavily based on
JNI concepts it is, essentially, JNI with a limited set of headers for C compilation.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Step 3: Adding Some C Code
Now, within the jni folder, create a file called native.c. Place the following C code in
this file to start; well add another function later:
#include <jni.h>
#include <string.h>
#include <android/log.h>
void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv
{
jboolean isCopy;
const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy)
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
parameter, converts it in to a C-string, and then writes it out to LogCat.
The name of the function, though, is important. It follows the specific pattern of
Java, followed by the package name, followed by the class name, followed by the
method name, as defined from Java. Every piece is separated by an underscore
instead of a dot.
The first two parameters of the function are critical, too. The first parameter is the
JNI environment, frequently used with helper functions. The second parameter is the
Java object that this function is a part of.
Then you have to add the function declaration on the Java side. Add the following
declaration to your Activity class:
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
private native void helloLog(String logThis);
This tells the compilation and linking system that the implementation for this method
will be from the native code.
Finally, you need to load the library that the native code will ultimately compile to.
Add the following static initializer to the Activity class to load the library by name
(the library name itself is up to you, and will be referenced again in the next step):
static {
System.loadLibrary("ndk1");
}
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := ndk1
LOCAL_SRC_FILES := native.c
include $(BUILD_SHARED_LIBRARY)
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
On subsequent compiles, you can make sure everything is recompiled if you use
the ndk-build clean command.
One of two things may have happened. First, it may have worked. If so,
congratulations! But you might want to read on, anyway. You probably got an error
to LogCat saying something like, Could not execute method of activity. This is fine.
It just means you missed a step. This is easy to do in Eclipse. Usually, Eclipse is
configured to recompile automatically. What it doesnt do is recompile and relink
automatically if it doesnt know anything has changed. And, in this case, what
Eclipse doesnt know is that you compiled the native code. So, force Eclipse to
recompile by cleaning the project (Project->Clean from the Eclipse toolbar).
jstring Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_getString(JNI
{
char *szFormat = "The sum of the two numbers is: %i";
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
char *szResult;
// standard sprintf
sprintf(szResult, szFormat, sum);
// cleanup
free(szResult);
return result;
}
For this to compile, youll want to add an include statement as well for stdio.h. And,
to correspond to this new native function, add the following declaration in your
Activity Java class:
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
private native String getString(int value1, int value2);
You can now wire up the functionality however you like. We used the following two
calls and outputs:
Back to the C function, youll note that we did a couple things. First, we create need
a buffer to write to for the sprintf() call using the malloc() function. This is
reasonable so long as you dont forget to free the results when youre done using
the free() function. Then, to pass the result back, you can use a JNI helper function
called NewStringUTF(). This function basically it takes the C string and makes a
new Java object out of it. This new String object can then be returned as the result
and youll be able to use it as a regular Java String object from the Java class.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Instruction Sets, Compatibility, Etc.
The Android NDK requires Android SDK 1.5 or later. In later versions of the NDK,
new headers have been made available for expanded access to certain APIsin
particular, OpenGL ES libraries.
However, thats not the compatibility were talking about. This is native code,
compiled to the processor architecture in use. So, one question you might be asking
yourself is what processor architectures are supported? In the current NDK (as of
this writing) only the ARMv5TE and ARMv7-A instruction sets are supported. By
default, the target is set to ARMv5TE, which will work on all Android devices with
ARM chips.
There are plans for further instruction sets (x86 has been mentioned). This has an
interesting implication: an NDK solution will not work on all devices. For instance,
there are Android tablets out there that use the Intel Atom processor, which has an
x86 instruction set.
So how does the NDK work on the emulator? The emulator is running a true virtual
machine, including full processor emulation. And yes, that means when running
Java within the emulator youre running a VM inside a VM.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Conclusion
How did you do? Did you get Android NDK installed and ultimately make a
functional, running application that uses native C code as part of it? We hope so.
There are many potential gotchas! along the way but in some cases, it can be
worth the effort. As always, wed love to hear your feedback.
Advertisement
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Advertisement
Translations Available:
Jobs
Advertisement
67 Comments Mobiletuts+
Sort by Best
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := libtest.so
include $(PREBUILT_SHARED_LIBRARY)
see more
5 Reply Share
i got that the path is not the one given here but it has to be
/Users/naveenkumar/Documents/workspace/JniHello/jni/Android.mk
where my Android.mk is present but i dont kw how to change APP_BUILD_SCRIPT to point to this locatio
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Michael, I'm running into the same problem as you, any chance you have figured it out?
Reply Share
I am working as Android Developer and at present i m working on configure FFMPEG library for Android. I
Google and i found your post it is so helpful , but first i need to build FFMPEG library for my application i ha
for do that, but its not working because i m using windows 8 and cygwin so some command is not workin
cygwin, it's give me error like c compiler dose not create executable file or c compiler not found...
Please, help me... give me any hint for how to build FFMPEG for my application
Reply Share
I import your code package and tried running but got this error
I tried finding the answer on stack overflow but nothing seems to work . Any help in this regard would be h
appreciated.
Thanks
Reply Share
That fixed it for me. Looks like the export and calling conventions are required now.
Reply Share
I would probably use a simpler allocation by "char szResult[100];" in order to avoid the malloc()/free() code
understand the point you are making regarding freeing any memory allocated for the parameters into (*en
>NewStringUTF().
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Sir how to call objective-c function from the android class and what to write in Android.mk
Reply Share
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
jni/native.c:1:17: warning: extra tokens at end of #include directive [enabled by default]
jni/native.c:2:20: warning: extra tokens at end of #include directive [enabled by default]
jni/native.c:3:25: warning: extra tokens at end of #include directive [enabled by default]
jni/native.c: In function 'Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog':
jni/native.c:8:38: error: 'gt' undeclared (first use in this function)
jni/native.c:8:38: note: each undeclared identifier is reported only once for each function it appears in
jni/native.c:8:74: error: 'amp' undeclared (first use in this function)
jni/native.c:8:77: error: expected ')' before ';' token
/cygdrive/c/android-ndk-r8c/build/core/build-binary.mk:260: recipe for target `obj/local/armeabi/objs/ndk1/n
failed
make: *** [obj/local/armeabi/objs/ndk1/native.o] Error 1
jni/native.c:1:17: warning: extra tokens at end of #include directive [enabled by default]
jni/native.c:2:20: warning: extra tokens at end of #include directive [enabled by default]
jni/native.c:3:25: warning: extra tokens at end of #include directive [enabled by default]
jni/native.c: In function 'Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog':
jni/native.c:8:38: error: 'gt' undeclared (first use in this function)
jni/native.c:8:38: note: each undeclared identifier is reported only once for each function it appears in
see more
Reply Share
c:/dev/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-
androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld.exe: BFD (GNU Binutils) 2.21 assertion fail
/usr/local/google/home/andrewhsieh/ndk-andrewhsieh/src/build/../binutils/binutils-2.21/bfd/elf32-arm.c:101
Reply Share
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
what is the reason behing problem?
Reply Share
I had a general question about using the NDK. Do I need to put the native code information in an Activity, o
be used in a regular class?
static {
System.loadLibrary("ndk1");
}
This is the code I am talking about. I would also like to make the methods static, so that every Activity I hav
access them. Do you know if this is possible?
Reply Share
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Jimmy 3 years ago
Hey,
In your example you say to call the native function, put the following in the default Activity. I currently have a
with multiple files written in C, and multiple Activities. Each Activity needs to call different methods from a
different C files. Is there any sort of declaration that tells the Activity where to look for the correct native me
does it just search the JNI folder on its own and find them?
Thanks,
Jimmy
Reply Share
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Jimmy > Andrew 3 years ago
Change the Path variables in your bash_profile file within the cygwin/home directory
Reply Share
Reply Share
Than You
Reply Share
Had a trouble with the extra spaces in the makefile but otherwise perfect.
Reply Share
APP_ABI: = x86
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Hwang 3 years ago
Thx from korea!
I have however a suggestion to improvement, you could mention that it is very important not to have any n
spaces in the Android.mk
When I copied your Android.mk from the site two whitespaces was inserted after LOCAL_PATH := (call m
gave me an unfriendly error and it was hard figuring out the cause, as always uncle internet saved my day
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Kiet 3 years ago
Thank you. Your demo is short and precise. I was able to pass data from C to Java. Just missing the add
Vinay pointed out.
Kiet
Reply Share
In the code:
the size of the char array allocated to szResult is 24 bytes as sizeof(szFormat) == 4 or 8 as szFormat is
char* (which is 4 bytes on a 32 bit machine and 8 bytes on a 64 bit machine). The results would have bee
if you had initialized szFormat as char[] szFormat = "..."; where upon sizeof(szFormat) would have given
size of the format string in bytes.
Please fix.
Thanks.
Reply Share
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Facebook App
Events
Reach Specific Sets of Your
Users with Facebook Mobile
App Ads.
Advertisement
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Get Tuts+ updates, news, surveys &
offers.
FAQ
Subscribe
Terms of Use
Contact Support Privacy Policy
About Tuts+
Advertise
Teach at Tuts+
Build anything from social networks to file upload systems. Build faster
with pre-coded PHP scripts.
Browse PHP on CodeCanyon
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
2014 Envato Pty Ltd. Trademarks and brands are the property of their respective
owners.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com