最新 将 MuPDF 编译到 Android 动态库 PDF解析渲染引擎

文章目录

MuPDF介绍

MuPDF 是用 C 写的、轻量快速、跨平台的开源 PDF解析渲染引擎,支持简单的编辑。

一.克隆仓库

bash 复制代码
git clone --recursive --depth=1 https://github.com/ArtifexSoftware/mupdf.git

二.配置ANDROID_NDK_HOME 环境变量

bash 复制代码
export ANDROID_HOME=/home/ml/Android/Sdk
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/29.0.14206865

export PATH=$PATH:$ANDROID_NDK_HOME

三.编写编译脚本

在mupdf项目根目录创建build_android.sh脚本

bash 复制代码
#!/bin/sh

# 默认 ABI
APP_ABI="arm64-v8a"

# 解析具名参数 --abi <架构>
while [ $# -gt 0 ]; do
    case "$1" in
        --abi)
            APP_ABI="$2"
            shift 2
            ;;
        *)
            echo "未知参数: $1"
            exit 1
            ;;
    esac
done

# 编译流程
rm -rf build/android
mkdir -p build/android

ndk-build -j4 \
  NDK_PROJECT_PATH=./build/android \
  APP_BUILD_SCRIPT=./platform/java/Android.mk \
  APP_PLATFORM=android-21 \
  APP_ABI="$APP_ABI" \
  APP_OPTIM=release 2>&1

四.赋予执行权限并执行

bash 复制代码
chmod +x build_android.sh

./build_android.sh

五.测试

  1. 将编译好的libmupdf_java.so放到android项目的 src\main\jniLibs\arm64-v8a 下(你编译的是什么架构就放在哪个架构下)
  2. 将mupdf项目下platform/java/src/的所有文件复制到android项目的 src\main\java 下

如图:

  1. 测试版本
kotlin 复制代码
@Composable
fun MainScreen() {
    val navBackStack = LocalNavBackStack.current

    var mupdfVersion by remember { mutableStateOf("未知") }

    LaunchedEffect(Unit) {
        runCatching {
            mupdfVersion = com.artifex.mupdf.fitz.Context.getVersion().version
        }.onFailure {
            mupdfVersion = "错误"
        }
    }

    Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
        Column(
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "MuPdf版本:$mupdfVersion")
            Button(onClick = {
                navBackStack?.add(NavRoute.PdfRender)
            }) {
                Text(text = "pdf渲染")
            }
            Button(onClick = {
                navBackStack?.add(NavRoute.PdfOperation)
            }) {
                Text(text = "pdf操作")
            }
        }
    }
}
  1. 版本结果
  2. 测试渲染
kotlin 复制代码
@Composable
fun PdfRenderScreen() {
    val context = LocalContext.current
    var pdfPath by remember { mutableStateOf<String?>(null) }

    var document by remember { mutableStateOf<Document?>(null) }
    var pageCount by remember { mutableIntStateOf(0) }
    var currentPage by remember { mutableIntStateOf(0) }


    DisposableEffect(pdfPath) {
        // 加载 PDF文档
        try {
            pdfPath?.let {
                val doc = Document.openDocument(it)
                document = doc
                pageCount = doc.countPages()
                currentPage = 0
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        onDispose {
            document?.destroy()
        }
    }

    val pickFileLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        uri?.let {
            try {
                val inputStream = context.contentResolver.openInputStream(it)
                val tempFile = File(context.cacheDir, "temp_${System.currentTimeMillis()}.pdf")
                FileOutputStream(tempFile).use { output ->
                    inputStream?.copyTo(output)
                }
                pdfPath = tempFile.absolutePath
            } catch (e: Exception) {
                Toast.makeText(context, "加载失败: ${e.message}", Toast.LENGTH_SHORT).show()
                e.printStackTrace()
            }
        }
    }

    Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier = Modifier
                .padding(innerPadding)
                .fillMaxWidth()
        ) {
            Button(onClick = { pickFileLauncher.launch("application/pdf") }) {
                Text("选择 PDF 文件")
            }
            Spacer(modifier = Modifier.height(16.dp))
            document?.let {
                PdfView(document = it, currentPage = currentPage, modifier = Modifier.weight(1f))
            }
            Row(modifier = Modifier.fillMaxWidth()) {
                Button(
                    onClick = {
                        currentPage = (currentPage - 1).coerceAtLeast(0)
                    },
                    enabled = currentPage > 0
                ) {
                    Text("上一页")
                }
                Spacer(modifier = Modifier.weight(1f))
                Button(
                    onClick = {
                        currentPage = (currentPage + 1).coerceAtMost(pageCount - 1)
                    },
                    enabled = currentPage < pageCount - 1
                ) {
                    Text("下一页")
                }
            }
        }
    }

}

@Composable
private fun PdfView(
    document: Document,
    currentPage: Int,
    modifier: Modifier = Modifier
) {
    val density = LocalDensity.current

    val bitmapState = produceState<Bitmap?>(null, document, currentPage) {
        value = withContext(Dispatchers.Default) {
            try {
                val page = document.loadPage(currentPage)

                val zoom = density.density * 2

                val pixmap = page.toPixmap(
                    Matrix().scale(zoom, zoom),
                    ColorSpace.DeviceRGB,
                    true
                )

                val bitmap = createBitmap(pixmap.width, pixmap.height)


                bitmap.copyPixelsFromBuffer(
                    IntBuffer.wrap(pixmap.pixels)
                )

                pixmap.destroy()
                page.destroy()

                bitmap
            } catch (e: Exception) {
                e.printStackTrace()
                null
            }
        }
    }

    val bitmap = bitmapState.value


    Box(
        modifier = modifier
            .background(Color.LightGray),
        contentAlignment = Alignment.Center
    ) {
        bitmap?.let {
            Image(
                bitmap = it.asImageBitmap(),
                contentDescription = null,
                modifier = Modifier
                    .padding(5.dp)
                    .zoomable(rememberZoomState())
            )
        } ?: run {
            CircularProgressIndicator()
        }
    }

}
  1. 渲染结果

六.裁剪库

  1. 修改mupdf项目下platform/java/Android.mk,禁用不需要的组件。
bash 复制代码
LOCAL_PATH := $(call my-dir)
MUPDF_PATH := $(realpath $(LOCAL_PATH)/../..)

ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
HAVE_NEON := yes
endif

ifeq ($(TARGET_ARCH_ABI),x86_64)
HAVE_AVX := yes
HAVE_AVX2 := yes
HAVE_FMA := yes
HAVE_SSE4_1 := yes
endif

include $(MUPDF_PATH)/Makelists

ifeq ($(USE_TESSERACT),yes)
ifeq ($(USE_LEPTONICA),)
USE_LEPTONICA := yes
endif
endif

# --- Build a local static library for core mupdf ---

include $(CLEAR_VARS)

LOCAL_MODULE := mupdf_core

LOCAL_C_INCLUDES := $(MUPDF_PATH)/include

LOCAL_CFLAGS += -ffunction-sections -fdata-sections
LOCAL_CFLAGS += -D_FILE_OFFSET_BITS=32
LOCAL_CFLAGS += -DTOFU_NOTO
LOCAL_CFLAGS += -DTOFU_CJK
LOCAL_CFLAGS += -DTOFU_SIL
LOCAL_CFLAGS += -DAA_BITS=8
LOCAL_CFLAGS += -DFZ_ENABLE_BARCODE=0

# 文档格式(仅保留 PDF)
LOCAL_CFLAGS += -DFZ_ENABLE_XPS=0
LOCAL_CFLAGS += -DFZ_ENABLE_SVG=0
LOCAL_CFLAGS += -DFZ_ENABLE_CBZ=0
LOCAL_CFLAGS += -DFZ_ENABLE_IMG=0
LOCAL_CFLAGS += -DFZ_ENABLE_HTML=0
LOCAL_CFLAGS += -DFZ_ENABLE_EPUB=0
LOCAL_CFLAGS += -DFZ_ENABLE_MOBI=0
LOCAL_CFLAGS += -DFZ_ENABLE_FB2=0
LOCAL_CFLAGS += -DFZ_ENABLE_TXT=0
LOCAL_CFLAGS += -DFZ_ENABLE_OFFICE=0

# 输出格式
LOCAL_CFLAGS += -DFZ_ENABLE_OCR_OUTPUT=0
LOCAL_CFLAGS += -DFZ_ENABLE_ODT_OUTPUT=0
# 禁用js和html
LOCAL_CFLAGS += -DFZ_ENABLE_JS=0
LOCAL_CFLAGS += -DFZ_ENABLE_HTML_ENGINE=0


LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(FREETYPE_CFLAGS)))
#LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(GUMBO_CFLAGS)))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(HARFBUZZ_CFLAGS)))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(JBIG2DEC_CFLAGS)))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(LCMS2_CFLAGS)))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(LIBJPEG_CFLAGS)))
#LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(MUJS_CFLAGS)))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(OPENJPEG_CFLAGS)))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(BROTLI_CFLAGS)))

ifdef USE_TESSERACT
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(TESSERACT_CFLAGS)))
endif
ifdef USE_LEPTONICA
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(LEPTONICA_CFLAGS)))
endif

LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(EXTRACT_CFLAGS)))

LOCAL_CFLAGS += $(filter-out -I%,$(FREETYPE_CFLAGS))
#LOCAL_CFLAGS += $(filter-out -I%,$(GUMBO_CFLAGS))
LOCAL_CFLAGS += $(filter-out -I%,$(HARFBUZZ_CFLAGS))
LOCAL_CFLAGS += $(filter-out -I%,$(JBIG2DEC_CFLAGS))
LOCAL_CFLAGS += $(filter-out -I%,$(LCMS2_CFLAGS))
LOCAL_CFLAGS += $(filter-out -I%,$(LIBJPEG_CFLAGS))
#LOCAL_CFLAGS += $(filter-out -I%,$(MUJS_CFLAGS))
LOCAL_CFLAGS += $(filter-out -I%,$(OPENJPEG_CFLAGS))
LOCAL_CFLAGS += $(filter-out -I%,$(BROTLI_CFLAGS))

ifdef USE_TESSERACT
LOCAL_CFLAGS += -DHAVE_TESSERACT
LOCAL_CFLAGS += $(filter-out -I%,$(TESSERACT_CFLAGS))
endif
ifdef USE_LEPTONICA
LOCAL_CFLAGS += -DHAVE_LEPTONICA
LOCAL_CFLAGS += $(filter-out -I%,$(LEPTONICA_CFLAGS))
endif

LOCAL_CFLAGS += $(filter-out -I%,$(EXTRACT_CFLAGS))

LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/fitz/*.c)
LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/fitz/*.cpp)
LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/pdf/*.c)
#LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/xps/*.c)
#LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/svg/*.c)
#LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/cbz/*.c)
#LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/html/*.c)
LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/source/helpers/pkcs7/*.c)

LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/generated/resources/fonts/urw/*.c)
LOCAL_SRC_FILES += $(wildcard $(MUPDF_PATH)/generated/resources/hyphen/*.c)

LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)

include $(BUILD_STATIC_LIBRARY)

# --- Build local static libraries for thirdparty libraries ---

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_freetype
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(FREETYPE_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(FREETYPE_CFLAGS) $(FREETYPE_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(FREETYPE_CFLAGS) $(FREETYPE_BUILD_CFLAGS))
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

#include $(CLEAR_VARS)
#LOCAL_MODULE += mupdf_thirdparty_gumbo
#LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(GUMBO_SRC))
#LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(GUMBO_CFLAGS) $(GUMBO_BUILD_CFLAGS)))
#LOCAL_CFLAGS += $(filter-out -I%,$(GUMBO_CFLAGS) $(GUMBO_BUILD_CFLAGS))
#LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
#include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_jbig2dec
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(JBIG2DEC_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(JBIG2DEC_CFLAGS) $(JBIG2DEC_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(JBIG2DEC_CFLAGS) $(JBIG2DEC_BUILD_CFLAGS))
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_harfbuzz
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(HARFBUZZ_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(HARFBUZZ_CFLAGS) $(HARFBUZZ_BUILD_CFLAGS)))
LOCAL_CPPFLAGS += $(filter-out -I%,$(HARFBUZZ_CFLAGS) $(HARFBUZZ_BUILD_CFLAGS))
LOCAL_CPPFLAGS += $(MUPDF_EXTRA_CPPFLAGS)
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_lcms2
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(LCMS2_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(LCMS2_CFLAGS) $(LCMS2_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(LCMS2_CFLAGS) $(LCMS2_BUILD_CFLAGS))
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_libjpeg
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(LIBJPEG_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(LIBJPEG_CFLAGS) $(LIBJPEG_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(LIBJPEG_CFLAGS) $(LIBJPEG_BUILD_CFLAGS))
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

#include $(CLEAR_VARS)
#LOCAL_MODULE += mupdf_thirdparty_mujs
#LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(MUJS_SRC))
#LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(MUJS_CFLAGS) $(MUJS_BUILD_CFLAGS)))
#LOCAL_CFLAGS += $(filter-out -I%,$(MUJS_CFLAGS) $(MUJS_BUILD_CFLAGS))
#LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
#include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_openjpeg
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(OPENJPEG_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(OPENJPEG_CFLAGS) $(OPENJPEG_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(OPENJPEG_CFLAGS) $(OPENJPEG_BUILD_CFLAGS))
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_brotli
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(BROTLI_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(BROTLI_CFLAGS) $(BROTLI_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(BROTLI_CFLAGS) $(BROTLI_BUILD_CFLAGS))
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

ifdef USE_TESSERACT
# --- Build local static library for tesseract ---

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_tesseract
LOCAL_C_INCLUDES := $(MUPDF_PATH)/include
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(TESSERACT_SRC))
LOCAL_SRC_FILES += $(MUPDF_PATH)/source/fitz/tessocr.cpp
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(TESSERACT_CFLAGS) $(TESSERACT_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(TESSERACT_CFLAGS) $(TESSERACT_BUILD_CFLAGS))
LOCAL_CFLAGS += -Wno-sign-compare
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
LOCAL_CPP_FEATURES := exceptions
include $(BUILD_STATIC_LIBRARY)

endif

ifdef USE_LEPTONICA
# --- Build local static library for leptonica ---

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_leptonica
LOCAL_C_INCLUDES := $(MUPDF_PATH)/include
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(LEPTONICA_SRC))
LOCAL_SRC_FILES += $(MUPDF_PATH)/source/fitz/leptonica-wrap.c
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(LEPTONICA_CFLAGS) $(LEPTONICA_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(LEPTONICA_CFLAGS) $(LEPTONICA_BUILD_CFLAGS))
LOCAL_CFLAGS += -Wno-sign-compare -DANDROID_BUILD
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

endif  #  USE_LEPTONICA

include $(CLEAR_VARS)
LOCAL_MODULE += mupdf_thirdparty_extract
LOCAL_SRC_FILES += $(patsubst %,$(MUPDF_PATH)/%,$(EXTRACT_SRC))
LOCAL_C_INCLUDES += $(patsubst -I%,$(MUPDF_PATH)/%,$(filter -I%,$(EXTRACT_CFLAGS) $(EXTRACT_BUILD_CFLAGS)))
LOCAL_CFLAGS += $(filter-out -I%,$(EXTRACT_CFLAGS) $(EXTRACT_BUILD_CFLAGS))
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)
include $(BUILD_STATIC_LIBRARY)

# --- Build the final JNI shared library ---

include $(CLEAR_VARS)

LOCAL_MODULE := mupdf_java

LOCAL_C_INCLUDES += $(MUPDF_PATH)/include

LOCAL_CFLAGS += -DHAVE_ANDROID
LOCAL_CFLAGS += $(MUPDF_EXTRA_CFLAGS)

LOCAL_SRC_FILES += $(MUPDF_PATH)/platform/java/mupdf_native.c

ifdef ADD_SOURCE_FILES
LOCAL_SRC_FILES += $(ADD_SOURCE_FILES)
LOCAL_CFLAGS += $(ADD_C_FLAGS)
LOCAL_C_INCLUDES += $(ADD_C_INCLUDES)
endif

LOCAL_STATIC_LIBRARIES += mupdf_core
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_freetype
#LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_gumbo
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_harfbuzz
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_jbig2dec
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_lcms2
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_libjpeg
#LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_mujs
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_openjpeg
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_brotli

ifdef USE_LEPTONICA
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_leptonica
endif
ifdef USE_TESSERACT
LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_tesseract
endif

LOCAL_STATIC_LIBRARIES += mupdf_thirdparty_extract

LOCAL_LDLIBS += $(MUPDF_EXTRA_LDLIBS)
LOCAL_LDLIBS += -ljnigraphics
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += -lz
LOCAL_LDLIBS += -lm

LOCAL_LDFLAGS := -Wl,--gc-sections
LOCAL_LDFLAGS += $(MUPDF_EXTRA_LDFLAGS)

include $(BUILD_SHARED_LIBRARY)
  1. 修改mupdf项目下platform/java/mupdf_native.c,注释掉
c 复制代码
...
/* #include "jni/dom.c" */
...
/* #include "jni/story.c" */
...
  1. 大概能减少3 ~ 4MB
相关推荐
Rick19932 小时前
mysql 慢查询怎么快速定位
android·数据库·mysql
2301_7717172111 小时前
解决mysql报错:1406, Data too long for column
android·数据库·mysql
dvjr cloi12 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
随遇丿而安14 小时前
第2周:`EditText` 不只是输入框,它是 Android 输入体验的第一道门
android
我命由我1234514 小时前
Kotlin 开发 - lateinit 关键字
android·java·开发语言·kotlin·android studio·android-studio·android runtime
一起搞IT吧15 小时前
Android性能系列专题理论之十:systrace/perfetto相关指标知识点细节含义总结
android·嵌入式硬件·智能手机·性能优化
Muyuan199817 小时前
27.RAG 系统中的上下文充分性判断:从 Chunk 数量、FAISS 距离到 LLM Relevance Gate
python·django·pdf·fastapi·faiss
小书房19 小时前
Kotlin的by
android·开发语言·kotlin·委托·by
jinanwuhuaguo20 小时前
(第二十八篇)OpenClaw成本与感知的奇点——从“Token封建制”到“全民养虾”的本体论地基
android·人工智能·kotlin·拓扑学·openclaw