I have needed to use MuPDF library in my android project. After some research, I have seen that there are many integration tutorials but, but integrated projects are developed on Eclipse. For projects on AndroidStudio+Gradle, there is no example. I mean there is no specific example which exactly refers to this issue. So, after achieving my goal, I want to share the steps publicly so that it can be reused by others.
1-First of all, get the source code of MuPDF, compile with as described in this link. Make sure that it runs on an android device, so that we could be sure that if we see any problem it is not related to MuPDF compilation.
2-Add a new library module with same package name of Mupdf (com.artifex.mupdfdemo) into your project. Copy all java files under mupdf/platform/android/src/com/artifex/mupdfdemo into this newly created package.
3- Copy res folder under /mupdf/platform/android under main directory of Mupdf module of your project. Edit AndroidManifest.xml file of the module if necessary. Omit unnecessary definitions. There is only application tag in my AndroidManifest.xml file and its content is:
4- Create a folder under mupdf/src/main. Name it as 'jniLibs'.
There should be compiled C files under mupdf/platform/android/obj/local/armeabi-v7a. Copy armeabi-v7a under jniLibs dir and augment it 3 times. Name other directories as armeabi, mips, x86.
5- Under mupdf module, edit build.gradle. Add following lines under android tag.
OS: Ubuntu 12.04
Gradle Version: 0.12.2
1-First of all, get the source code of MuPDF, compile with as described in this link. Make sure that it runs on an android device, so that we could be sure that if we see any problem it is not related to MuPDF compilation.
2-Add a new library module with same package name of Mupdf (com.artifex.mupdfdemo) into your project. Copy all java files under mupdf/platform/android/src/com/artifex/mupdfdemo into this newly created package.
3- Copy res folder under /mupdf/platform/android under main directory of Mupdf module of your project. Edit AndroidManifest.xml file of the module if necessary. Omit unnecessary definitions. There is only application tag in my AndroidManifest.xml file and its content is:
android:allowbackup="true"
android:label="@string/app_name"
4- Create a folder under mupdf/src/main. Name it as 'jniLibs'.
There should be compiled C files under mupdf/platform/android/obj/local/armeabi-v7a. Copy armeabi-v7a under jniLibs dir and augment it 3 times. Name other directories as armeabi, mips, x86.
5- Under mupdf module, edit build.gradle. Add following lines under android tag.
sourceSets.main {
jniLibs.srcDir 'src/main/jniLibs'
}
That is it. I have inserted java files too, because I aim to use them in my project. If you don't need them, if you just want to use compiled C files, you can directly pass to 4th and 5th steps and apply them to the app module.
I am new at this structure. So, this is my solution and it may not be best. If you see any step as a bad practice, please drop your recommendation as a comment. I 'd always like to follow the best ways of what I do ;)OS: Ubuntu 12.04
Gradle Version: 0.12.2
THANK YOU, THANK YOU, THANK YOU!!!!!!!! Helped me a lot!!
ReplyDeleteHi. The link in your first step is not reachable. Any other sources ? Thanks
ReplyDeleteI have fixed it. Thanks for informing.
DeleteHi, thx a lot for this great Tuto.
ReplyDeleteandroid/obj/local/armeabi-v7a folder is pretty huge. are all files and folders needed to be copied in the jniLibs folder ?
thx.
It is the output of ndk compilation. So, yes. But you can omit augmenting part depending on your case.
DeleteHi,
DeleteThx for your answer. Augmenting part is needed to support all proc architecture, isn't it ?
Regards.
Yes. Different architecture will look for the directory associated to it.
DeleteYour genius man
ReplyDeleteI got the error:
ReplyDeleteGradle DSL method not found: `main()`
- The project MY_PROJECT_NAME may be using a version of Gradle that does not contain the method.
- The build may be missing a Gradle Plugin.
Please note that when i remove these lines from build.gradle of MuPDF the error disappears:
ReplyDeletesourceSets.main {
jniLibs.srcDir 'src/main/jniLibs'
}
What is your gradle version?
DeleteHow did you solve this?
DeleteHi, step is in the app or in the mupdfdemo ?
ReplyDeletestep 4
DeleteIn the new library module created in step 2.
DeleteIs ti possible to have your project source code ?
ReplyDeleteI'm getting a "Cannot open document" error. Any idea why ?
ReplyDeleteOne of the reasons for this error is "broken" file or "incomplete" download of file.
DeleteThank you very much for this article! Been trying to get it to working for four days and this is the only thing that worked! :D
ReplyDeletei got idea
ReplyDeleteI guess muPDF have changed the project structure a bit. For example, now they have started viewer package.
ReplyDeleteI just followed every step, and everything is working well. Thanks to clear guidelines in this blog.
But after integrating muPDF 1.9 ( I did not cloned source from git but downloaded from their download link) and it made apk size 10 MB to 59.9 MB. for previous versions of muPDF (1.3), it did not increased this much of size. Any one else faced such problem?
Well done!!!!
ReplyDeleteThanks for taking the time to write this. You're great!!!
" There should be compiled C files under mupdf/platform/android/obj/local/armeabi-v7a. Copy armeabi-v7a under jniLibs dir and augment it 3 times. Name other directories as armeabi, mips, x86. " For me , don even have obj folder , you mean these file will auto compiled after we create jnilib ?
ReplyDeleteForgive me if the question sounds naive as I am not at all familiar with ndk, native code integration and make files.
ReplyDeleteMy question is, does the above mentioned process to integrate mupdf, change with the ndk integration changes that google introduced with android studio 2.2+ and gradle 2.2.0+? Can we directly link the mupdf Makefile in android studio and start using mupdf library? What changes do I need to make in the integration process if I do NOT want to use "android.useDeprecatedNdk=true" in my project?
I would really appreciate any guidance that I could get.
Thanks.
Great work, This tutorial is awesome so thank you
ReplyDeleteI have a problem in step 1 - I built but app is crashing when I try it on emulator(API 19 with x86 processor)
It is great if you have Idea why this may happen
This is the logcat message
E/AndroidRuntime( 2464): FATAL EXCEPTION: main
E/AndroidRuntime( 2464): Process: com.artifex.mupdfdemo, PID: 2464
E/AndroidRuntime( 2464): java.lang.UnsatisfiedLinkError: Couldn't load mupdf_java32 from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.artifex.mupdfdemo-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.artifex.mupdfdemo-2, /system/lib]]]: findLibrary returned null
E/AndroidRuntime( 2464): at java.lang.Runtime.loadLibrary(Runtime.java:358)
E/AndroidRuntime( 2464): at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 2464): at com.artifex.mupdfdemo.MuPDFCore.(MuPDFCore.java:15)
E/AndroidRuntime( 2464): at com.artifex.mupdfdemo.MuPDFActivity.openFile(MuPDFActivity.java:229)
E/AndroidRuntime( 2464): at com.artifex.mupdfdemo.MuPDFActivity.onCreate(MuPDFActivity.java:359)
E/AndroidRuntime( 2464): at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime( 2464): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 2464): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
E/AndroidRuntime( 2464): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime( 2464): at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime( 2464): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime( 2464): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 2464): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 2464): at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime( 2464): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2464): at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 2464): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime( 2464): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime( 2464): at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager( 1571): Force finishing activity com.artifex.mupdfdemo/.MuPDFActivity
W/ActivityManager( 1571): Force finishing activity com.artifex.mupdfdemo/.ChoosePDFActivity
Getting this error
ReplyDeleteError: executing external native build for ndkBuild mupdf-android-viewer-mini\libmupdf\platform\java\Android.mk
How to resolve this error,please help me
link is not working. .... mentioned in step 1
ReplyDelete