将MuPDF作为库项目集成(Android)

7
所以我基于pdf阅读器(MuPDF)构建了这个项目。我使用ndk-build来构建它。这个项目的名字是ChoosePDFActivity。我知道它已经正确构建,因为我可以在我的libs/armrabi-v7a/THISISTHEFILE.so文件夹中看到一个.so文件。我的问题是,我如何正确地将这个项目作为库项目并从另一个项目中运行它?
我尝试将它标记为库项目并将其添加到我的主项目的构建路径中,但是我得到了“ExpressionInitializerError,无法加载库,FindLibrary返回NULL错误”的错误。请注意,我正在使用Mupdf-1.5(当前最新版本)。
那么我该怎么办呢?我的库的名称是libmupdf。请注意,我是android-ndk的新手。我的主项目中没有任何jni文件夹,只有在库项目中才有。以下是完整的错误信息。
06-16 17:51:27.680: E/AndroidRuntime(5673): 致命错误:主要异常 06-16 17:51:27.680: E/AndroidRuntime(5673): 在java.lang.Class.newInstanceImpl(Native Method)处产生异常 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.app.Instrumentation.newActivity(Instrumentation.java:1025)处创建新活动 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871)处执行活动启动 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)处处理活动启动 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.app.ActivityThread.access$600(ActivityThread.java:123)处访问线程 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)处处理消息 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.os.Handler.dispatchMessage(Handler.java:99)处分派消息 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.os.Looper.loop(Looper.java:137)处循环 06-16 17:51:27.680: E/AndroidRuntime(5673): 在android.app.ActivityThread.main(ActivityThread.java:4424)处运行主线程 06-16 17:51:27.680: E/AndroidRuntime(5673): 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)处运行ZygoteInit方法和参数的调用者 06-16 17:51:27.680: E/AndroidRuntime(5673): 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:592)处运行ZygoteInit主函数 06-16 17:51:27.680: E/AndroidRuntime(5673): 在dalvik.system.NativeStart.main(Native Method)处运行NativeStart主函数 06-16 17:51:27.680: E/AndroidRuntime(5673): 导致这个错误的原因是:无法加载libmupdf库,findLibrary返回null 06-16 17:51:27.680: E/AndroidRuntime(5673): 在java.lang.Runtime.loadLibrary(Runtime.java:365)处加载库 06-16 17:51:27.680: E/AndroidRuntime(5673): 在java.lang.System.loadLibrary(System.java:535)处加载库 06-16 17:51:27.680: E/AndroidRuntime(5673): 在com.mainpackage.MainActivity.(MainActivity.java:44)处引起异常

请帮助我,这个问题困扰我已经几天了。提前感谢。

这是我的 Android.mk 文件:

LOCAL_PATH := $(call my-dir)
TOP_LOCAL_PATH := $(LOCAL_PATH)

MUPDF_ROOT := ../..

ifdef NDK_PROFILER
include android-ndk-profiler.mk
endif

include $(TOP_LOCAL_PATH)/Core.mk
include $(TOP_LOCAL_PATH)/ThirdParty.mk

include $(CLEAR_VARS)

LOCAL_C_INCLUDES := \
    jni/andprof \
    $(MUPDF_ROOT)/include \
    $(MUPDF_ROOT)/source/fitz \
    $(MUPDF_ROOT)/source/pdf
LOCAL_CFLAGS :=
LOCAL_MODULE    := mupdf
LOCAL_SRC_FILES := mupdf.c
LOCAL_STATIC_LIBRARIES := mupdfcore mupdfthirdparty
ifdef NDK_PROFILER
LOCAL_CFLAGS += -pg -DNDK_PROFILER
LOCAL_STATIC_LIBRARIES += andprof
else
endif

LOCAL_LDLIBS    := -lm -llog -ljnigraphics
ifdef SSL_BUILD
LOCAL_LDLIBS    += -L$(MUPDF_ROOT)/thirdparty/openssl/android -lcrypto -lssl
endif

include $(BUILD_SHARED_LIBRARY)

这是我的项目快照。有两个突出的项目,它们正被讨论,其中ChoosePDFActivity是库项目。 enter image description here好吧,只需要像这样的东西就可以适用于我的情况: 有没有可能在我的最终构建中包含整个项目?我只需要从我的主项目传递一个意图给它,其他所有事情都将由ChoosePdf...项目处理。

P.S. 我注意到只有armeabi-v7a才能使用。那么,是否有任何方法可以为其他架构构建mupdf?

编辑 对于那些想在Android上进行PDF渲染的人,Android L(终于)获得了使本地PDF渲染成为可能的API。

2个回答

2
你只需要创建一个虚拟动态库,简单地链接到你的静态库,像这样:https://dev59.com/1HA85IYBdhLWcg3wF_i0#2957386。不幸的是,ndk构建系统不会创建未被动态库使用的静态库。然后,你只需从obj/local/armeabi-v7a中获取你的静态库即可。

那就是,除非你只想使用你的动态库。如果是这种情况,只需将它复制到<your_project>/lib/armeabi-v7a/中,它就会被包含在内。然后,你可以调用System.loadLibrary("THISISTHEFILE")。 - JonnyBoy
做了这件事,然后遇到了这个错误:[2014-06-17 09:13:59 - Marks++]生成最终归档文件时出错:发现重复的APK文件:lib / armeabi-v7a / libmupdf.so 来源1:C:\Users\Harsh\git\marks\Marks++\libs\armeabi-v7a\libmupdf.so 来源2:C:\muPDFLIB\mupdf-1.5-source\platform\android\libs\armeabi-v7a\libmupdf.so - harveyslash
请发布您的 Android.mk 文件。 - JonnyBoy

1
如果您的项目没有jni/文件夹,并且将库放置在libs/中,则不需要任何NDK技巧,它们会在那里。 (以防万一,请将它们放在版本控制下;默认情况下,.so通常被忽略。)
您日志中最重要的行是:
Caused by: java.lang.UnsatisfiedLinkError: Couldn't load libmupdf

如果您的项目使用了两个库,您需要按照解决依赖关系的顺序加载这两个库。
static {
    System.loadLibrary("tools"); // libtools.so
    System.loadLibrary("main"); // libmain.so
}

据我所知,您没有链接器问题,但为了保险起见,我会贴出以下链接:
关于如何构建共享库并在其他ndk程序中调用它的问题的回复
Android NDK-制作两个相互调用的本地共享库
使用预编译的静态库进行Android NDK链接

好的,我完全是新手。我真的不明白你的意思。 你说将库放置在libs/文件夹中是什么意思? 这是否意味着.so文件? - harveyslash
我添加了一个项目树的图片,请查看。 - harveyslash
"in the libs/" 表示 libs/armeabi-v7a/THISISTHEFILE.so 是正确的。(请注意,libs/armrabi-v7a/THISISTHEFILE.so 中有一个拼写错误) - 18446744073709551615
尝试从我的主项目加载库,但它无法工作 - 那么错误信息是什么?如果缺少另一个库,则也必须加载该库。尝试从hello-jni示例中开始使用库。此外,Eclipse有时会忽略依赖项,因此需要构建/重新构建。 - 18446744073709551615
Caused by 部分是什么内容? - 18446744073709551615
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接