Id like to use mupdf as a pdf viewer inside my own android app.
Ive been able to compile it (not easy) from instructions here , the last steps were :
ndk-build
ant debug
Now, how to call mupdf from my android project in eclipse ?
I just want to open a window with a specified PDF and a custom toolbar.
The mupdf.c is a wrapper of the native code, and the function that can be called by java code must have prefix such as com_artifex_mupdf_MuPDFCore.
In its function name Java_com_artifex_mupdf_MuPDFCore_openFile, com_artifex_mupdf_MuPDFCore is exactly the package name of the java code which declared the native functions, check out MuPDFCore.java, each native function are declared by using native keyword. Then you can use these functions like normal java methods.
BTW, mupdf is NOT thread safe, your JNI java code should be careful to use synchronized. The open source project VuDroid is also a good example to learn how to interact with mupdf via JNI.
Related
I have function implemented in C++ with several parameters and outputs. I want to use this function in my Android Studio Java code as a black box to pass necessary arguments and get results. The problem is that C++ function uses several libraries such as OpenCV together with other C++ implemented functions. I read about NDK and JNI and tried to do simple "Hello from C++" function call and it works. However, I do not understand how to install all libraries to C++ and how to put all necessary C++ codes.
You can find nice tutorial about JNI here.
We have developed an iPad application where the core logic is written in CPP code, so that we can use the same code files/libraries to other platforms.
Now I want to use those files and develop similar Android application, but unable to create .so files and integrate paths in Android.mk files and all. I am basically an iOS developer, this is first time I am looking into Android NDK.
Can anyone help and guide if there is any straight forward steps to it.
I have already gone through android developers site and few other tutorial sites. But none of those worked for me.
Require easy-clear steps to call cpp method in java, if I do have few cpp files and .a libraries with me already.
You aren't very specific at the step you are stuck at.
Here's a very quick explanation on how to call native code from java (android) :
first create a method to be exported by the native and called by java (this uses JNI, so google JNI , JNIEXPORT)
once you have this method defined in your native code, it's time to create a shared library (.so) file , using the compiler that comes in the NDK (because you are compiling for android ). You will need to compile for the correct architecture of the device (armeabiv7s is the most common now days).
you need to add the library file in your app.apk inside the armeabi folder (more details in NDK tutorials).
inside your java code you will need to load the shared library via the System.loadLibrary(LIBRARY_NAME);
inside your java code you will need to have defined static native methods that are in pair with the methods you exported from your CPP code
Quick tips :
use C functions,not CPP , since CPP will be mangled in the resulting shared library. In other words, you will need to create a C wrapper that will call your cpp code.
look over a hello world tutorial for NDK , and work yourself from there . Here's a link to such tutorial http://trivedihardik.wordpress.com/2011/06/16/hello-world-example-using-ndk-in-android/
You will bump later on into compilation issues with the makefiles, but by then you will probably be able to be more specific with your question.
Easiest way is to use the hello-jni Android studio sample project.
There are a lot of settings and configurations, you get them from the sample that is a working unit, always easiest when starting from something working.
First run (and modify) the hello-jni and learn how the interactivity between the Java and C parts works. About everything works except environmental ANSI C/C++ stuff. You have to get things like language, country etc from Java and transfer it to the C-code. You are in US in English with "inches and gallons" in JNI.
Then to an own project you create with android studio, copy and modify from it bit by bit from hello-jni. When you have our own branded hello-JNI you can add bit by bit your own code. Often using C-dummies for testing the interactivity with the Java part is easier, then change it to the real C/C++ code of yours.
Read the Android/Android studio documentation and learn and understand. Use the Android emulators, much easier and they are good.
The project configuration stuff is by far the hardest to handle at the start. If I would make a new project today, I would start from the Hello-JNI once again.
I want to reuse the .so file (created by using the ndk-build in one Android App) in another android app. It seems that the JNI convention needs the class from which the native code will be called.
I got the answer of a companion jar file from the following link
Re-use code Android NDK
But how to create it. Could someone elaborate it more.
I am working on android project.I have created a native edittext.I want use native jni function
in other android c++ project for display the edittext in c++.whenever i add the headerfile of
jni and edittext,then compiler does not find.
Can you suggest me.how to add native edittext project with my own project and how to use jni function with c++.
Your suggestion will helpful.
Take your code you want to share and place it into it's own compiled library. Then you can reference it in both the android project and the c++ project and use the code in both.
How to create and use static librarys in c++
How to add libraries in C++?
I am writing an Android application. I am implementing some of the app in C++ using JNI. Is there a way to actually separate completely the JNI (C++) code from the Java Android code? Like creating a JNI project or something ? Because my C++ code will become a little library that I will use in another app. I tried to create a C++ project but I can't compile with ndk-build.
In actuality, the tie-in between the Java and native code is fairly loose, in that it is done by the names of the methods at runtime.
The NDK is just a special environment and libraries for a C compiler. A suitable dynamic library file must be produced, but this can be done using the ndk script, using an ndk generated "stand alone tool chain" or even done before (or after, see later) the java project build, done on another machine, etc.
Normally the .so dynamic library gets copied into the appropriate place in the application project tree such that it will end up packaged in the .apk and installed on the device where it can be automatically found by the System.loadLibrary() method. But you could just insert it into the otherwise finished .apk (which is a zip file with special alignment and jarsigner signatures). But even the .pak is not actually not the only way to deliver it to the device (though it is the only recommended way)- a library can also be stored in a place such as the app's private folder and loaded using System.load() which takes a full pathname instead of a library name.
hotverspicy does have a point that the java code needs a native method "declaration" for what is implemented in the jni library, and that this needs to match the actual package name as encoded in the name of the native function implementation. However, that package name does not have to be the same as the rest of the java code - it could be something generic for the re-usable C/C++ library, which would require only one brief matching java class file in the matching java package name.
But in addition to Neevek's idea of using one native lib to interface to another, it is also likely possible to use an object factory mechanism to hook up arbitrary native functions at runtime, given just one association set up at compile time - see the relevant answer to C/C++ Reflection and JNI - A method for invoking native code which hasn't been written yet
If you use JNI in your C++ code, then it's bound to Android, and it must be an Android project with properly defined Android.mk, Application.mk(optional).
If you don't use JNI API in your code, say you want to create a generic library, you can just write your C++ code, compile it, test it as usual, no ndk-build is needed. When you finish coding with the library, build the code as a static library, and when you want to use this static library in your Android project, write some JNI wrappers around functionalities in the static library that you want to use, link against the static library in your Android.mk, something like this:
include $(CLEAR_VARS)
LOCAL_MODULE := libgeneric
LOCAL_SRC_FILES := prebuilt/libgeneric.a
include $(PREBUILT_STATIC_LIBRARY)