Here’s a screen shot
Step By Step Instructions below:
Step #1: Compile the project using ant. Some snippets are shown below.
NativeAdd.java class (with Native method)
package org.apache; import android.util.Log; public class NativeAdd { static { try { Log.i("JNI", "Trying to load libNativeAdd.so"); System.loadLibrary("NativeAdd"); } catch (UnsatisfiedLinkError ule) { Log.e("JNI", "WARNING: Could not load libNativeAdd.so"); } } public static native long add(long a, long b); }
Snippet that shows how this class/method is invoked from the main activity
public void onClick(View view) { Log.i(LOG_TAG, "onClick"); EditText a = (EditText) findViewById(R.id.a); EditText b = (EditText) findViewById(R.id.b); EditText c = (EditText) findViewById(R.id.c); Log.i(LOG_TAG, "calling native method"); long sum = NativeAdd.add(Long.parseLong(a.getText().toString()), Long.parseLong(b.getText().toString())); Log.i(LOG_TAG, "back from native method"); String text = Long.toString(sum); c.setText("Native add returns = " + text.subSequence(0, text.length())); }
Step #2: Generate header files using java by running the following command.
javah -classpath ../../android.jar;../bin/classes; org.apache.NativeAdd
Here’s how the header file (org_apache_CallNative.h) looks like
/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class org_apache_NativeAdd */ #ifndef _Included_org_apache_NativeAdd #define _Included_org_apache_NativeAdd #ifdef __cplusplus extern "C" { #endif /* * Class: org_apache_NativeAdd * Method: add * Signature: (JJ)J */ JNIEXPORT jlong JNICALL Java_org_apache_NativeAdd_add (JNIEnv *, jclass, jlong, jlong); #ifdef __cplusplus } #endif #endif
Step #3: Code a tiny C file (org_apache_NativeAdd.c) as shown below:
#include "org_apache_NativeAdd.h" JNIEXPORT jlong JNICALL Java_org_apache_NativeAdd_add (JNIEnv *env, jclass c, jlong a, jlong b) { return a + b; }
Step #4: Please read the following article before you try the next step.
Shared library “Hello World!” for Android
Step #5: Compile and link the org_apache_NativeAdd.c/org_apache_NativeAdd.h into a shared library.
arm-none-linux-gnueabi-gcc -I/usr/lib/jvm/java-1.5.0-sun/include -I/usr/lib/jvm/java-1.5.0-sun/include/linux -fpic -c org_apache_NativeAdd.c arm-none-linux-gnueabi-ld -T armelf_linux_eabi.xsc -shared -o libNativeAdd.so org_apache_NativeAdd.oNOTE: details on armelf_linux_eabi.xsc are in the Step #4. Step #6: copy the library to the emulator. Copy the Application as well.adb push native/libNativeAdd.so /system/lib adb install bin/CallNative.apkStep #7: Run the app to try some values. That's it!
Download the sources and Application - CallNative.zip
[…] http://euedge.com/blog/2007/12/06/google-android-runs-on-sharp-zaurus-sl-c760https://davanum.wordpress.com/2007/12/09/android-invoke-jni-based-methods-bridging-cc-and-java […]
Pingback by Android Internals « $HOME — December 30, 2007 @ 11:49 pm
[…] capture video or use location based services, you may however try to use JNI. Davanum Srinivas presents how to achieve this step by step. This way one can make part of his app partially native to gain performance, for instance in case […]
Pingback by Do Android dream of something more than Java? « Mantrid’s Weblog — April 28, 2008 @ 3:53 am
thanks for the infomation
the CallNative.zip download is not work, can you fix that?
thanks
Yael
Comment by Yael — December 7, 2008 @ 6:16 am
[…] example […]
Pingback by Yu-Teh Wiki: Jni — January 31, 2009 @ 8:36 pm
[…] Android by Davanum […]
Pingback by Hello World на Си для андроида | Androider — March 14, 2009 @ 6:31 am
[…] some C (or C++) code (perhaps for speed-sensitive code paths)? A. One can do that, using JNI. A blog post on this topic. « Porting Android kernel to the TS-72xx […]
Pingback by A few “Android FAQs for Beginners” Answered « KaiwanTech’s Blog — March 23, 2009 @ 3:02 am
can you Explain this?
“javah -classpath ../../android.jar;../bin/classes; org.apache.NativeAdd”
what do you mean by “bin/classes”? and where should I store android.jar?
Comment by paresh — April 2, 2009 @ 7:16 am
Thanks for this very good introdurction to using JNI on Android.
I am using Windows XP with JDK1.6.0 and I got some problems which I could solve. So here is a short description of how I got it running:
Rewriting …/include/linux to …/include/win32 did not work:
The problem seems to be the declaration for __int64 (as long long) and the __stdcall and __declspec(x) compiler directive in “include/win32/jni_md.h”.
I solved this by definig them on the command line:
Now it works!
For linking the file “armelf_linux_eabi.xsc” is needed.
It can be found under the Sourcery G++ Lite program dir: …\arm-none-linux-gnueabi\lib\ldscripts\armelf_linux_eabi.xsc
Using the default installation of Sourcery G++ Lite the link command is as follows:
Next suprise: No acces right to copy into “/system/lib” using adb push
Copied it to “/data”
and changed the loadLibrary in NativeAdd.java
And… SUCCESS!!! 🙂
Hope this might help others to get things working under windows,
Best regards,
Feri
Comment by Ferenc Hechler — April 2, 2009 @ 9:37 am
The above step by Ferenc Hechler also worked fine for me too. Thanks for that. Just to add to that you can get arm-none-linux-gnueabi-gcc from https://support.codesourcery.com/GNUToolchain for free having evaluation period of 30 days.
Want to know, if the same .so library, that worked on windows will work on device?
Comment by shruthirap — May 18, 2009 @ 7:32 am
i am getting jni.h :no such file or directory error
Comment by satya — December 28, 2009 @ 1:44 am
Thanks for the infomation!!!
the CallNative.zip download is not work, can you fix that?
thanks!!!
Comment by david — May 20, 2009 @ 4:03 am
With emulator,I have push libNativeAdd.so in to System/lib is OK, but with G1, i can’t push System/lib,
Please help How to push libNativeAdd.so into System/lib or using System.loadLibrary(“NativeAdd”);
Comment by can't push libNativeAdd.so in System/lib — June 3, 2009 @ 8:40 pm
I have big problem . When I try to “push” my library on /system/lib, The emulator is OK, but The production T-mobile G1 tell me that partition is read only.
Then, i’ve tried to push the library on another location and use the method system.load instead of system.loadlibrary. In this way I can load the library.
Please tell me, How to do push my library in to System/lib in T-mobile G1 or using System.loadLibrary(“NativeAdd”) with T-mobile G1.
thanks,
p-d-Quang
Comment by pdquang — June 3, 2009 @ 9:30 pm
It works in my G1 puting my library inside apk zip file and extracting that on /data/data/MY_PACKAGE (based on this code http://www.netmite.com/android/mydroid/external/androidmono/MonoBridge/src/com/koushikdutta/mono/MonoActivity.java)
Comment by victor — June 15, 2009 @ 8:08 am
also using System.load(“/data/data/MY_PACKAGE/MY_LIBRARY”) instead of System.loadLibrary
Comment by victor — June 15, 2009 @ 8:11 am
[…] Davanum Srinivas […]
Pingback by Android JNI Blogs « Heejin Kim — June 17, 2009 @ 12:46 pm
Screenshot doesn’t work 😦
Comment by Mohammed Khoory — June 20, 2009 @ 12:42 am
Hi All,
I am a newbie on android platform.
my query goes like this, I want to develop my api to the Android OS by submitting it to the Android OS source on my local machine.
eg:
I have MathLib.java which has add() native method. Which i suppose need to be implemented in c/cpp.
I do not understand
1. where do i keep this java file in directory structure?
2. do i need to create .class and .h files manually or build system takes care of it?
3. where shud my libmathlib.so reside?
4. where do i keep cpp implementation file in dir stuctur?
if anyone has some documents please fwd them to me.
I hope u have understood what i am looking for.
Thanks and regards,
Anu
Comment by Anu — March 9, 2010 @ 5:45 am
now you can use android ndk
take a look:
http://developer.android.com/sdk/ndk/index.html
Comment by Victor — March 9, 2010 @ 7:49 pm
if you using System.loadLibrary(“mathlib”) please push libmathlib.so to system/lib
and if you use SystemLoad(“Path relative”) Please push libmathlib.so to Path relative.
Comment by Quang Pham — March 9, 2010 @ 10:07 pm
You can also use JNIpp to simplify creations of Java class wrappers.
That way you can have the whole application including activity and views in native code.
See https://github.com/DmitrySkiba/itoa-jnipp/blob/master/android/samples/HelloJNIpp/jni/Main.cpp
Comment by Dmitry — June 10, 2011 @ 5:59 am
[…] https://davanum.wordpress.com/2007/12/09/android-invoke-jni-based-methods-bridging-cc-and-java/ […]
Pingback by [Android] add the JNI in android | SoftBlog — October 24, 2011 @ 5:56 am
Hi All,
I am doing project in android in which I require libraries plus c code of linux..Will anyone guide me how am I include these codes and libraries in android??
Thanks in Advance
Comment by naeem898 — March 8, 2012 @ 12:36 pm
hi,
I have tried writing a jni call for the simple c code. when i try to install this on the phone running 2.3.3 it doesnt install, sometimes even if it installs then it is being force closed.Please help me with this. the code details are as follows:
The java code of which i generate the header file.
package com.hosa;
public class edgejava{
static{
System.loadLibrary(“edgejava”);
}
public native int main();
}
the generated header file is as below
/* DO NOT EDIT THIS FILE – it is machine generated */
#include
/* Header for class com_hosa_edgejava */
#ifndef _Included_com_hosa_edgejava
#define _Included_com_hosa_edgejava
#ifdef __cplusplus
extern “C” {
#endif
/*
* Class: com_hosa_edgejava
* Method: main
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_hosa_edgejava_main
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
the implementation of native function is as below
#include “com_hosa_edgejava.h”
#include
#include
#include
using namespace cv;
JNIEXPORT jint JNICALL Java_com_pes_edgejava_main(JNIEnv *, jobject){
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
namedWindow(“edges”,CV_WINDOW_AUTOSIZE);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow(“edges”, edges);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
the android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include /home/srijith/android-opencv/OpenCV-2.3.1/share/OpenCV/OpenCV.mk
LOCAL_MODULE := edgejava
LOCAL_SRC_FILES := edgecpp.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
the application.mk
APP_MODULES := edgejava
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
the activity file is as follows
package com.hosa;
import android.app.Activity;
import android.os.Bundle;
public class Andedge2Activity extends Activity {
edgejava nativelib;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nativelib= new edgejava();
int i=nativelib.main();
System.out.println(“value returned to andedgeactivity “+i);
}
}
All necessary changes to the manifest has been done like mention of use of camera and permissions has been set.
Comment by gaurav — April 13, 2012 @ 3:11 am
[…] This article explains it quite well: https://davanum.wordpress.com/2007/12/09/android-invoke-jni-based-methods-bridging-cc-and-java/……………………………. […]
Pingback by Native C/C++ code on an Android platform | Android Development tutorial | Android Development tutorial — June 24, 2012 @ 6:46 am