EVER PAGE / ANDROID
文档能力,按需接入。
将 PDF 查看、文本搜索与手势浏览集成到 Android 应用。选择自己的页面,或由 SDK 提供独立阅读页面。
Android 9+ · API 28+KotlinPDF01 / 选择接入模块
| 模块 | 适用需求 | 包含能力 |
|---|---|---|
| 业务自有标题栏和页面 | PDF、搜索、滑动、缩放和阅读状态 | |
| ui | 默认 UI 与阅读进程隔离 | 包含 pdf,提供独立 Activity 和返回结果 |
| all | 全部已实现能力 | 当前聚合 pdf 与 ui,不重复打包引擎 |
只需声明所选模块,上层模块自动引入必要依赖。编辑、批注、Office 和转换尚未提供,不包含在当前全量模块中。
02 / 安装与依赖
当前通过本地 Maven 仓库交付,尚未发布到 Maven Central。获取完整仓库目录后,将其配置为项目仓库;只复制单个 AAR 会丢失传递依赖信息。
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri(providers.gradleProperty("everpageRepository").get()) }
}
}在本地 gradle.properties 中将 everpageRepository 设置为收到的 Maven 仓库绝对路径;请勿提交个人路径。
android {
compileSdk = 36
compileSdkExtension = 19
defaultConfig { minSdk = 28 }
}
dependencies {
implementation("work.firstlook.everpage:everpage-pdf:0.1.0-alpha01")
}同一应用内使用相同版本的 Ever Page 模块。当前坐标为本地交付版本,不代表远程仓库可以直接下载。
03 / 嵌入业务页面
依赖 pdf 模块,在业务布局中预留内容容器。标题栏、返回操作与系统栏继续由业务控制。
import com.transsion.xreader.XReader
import com.transsion.xreader.core.OpenRequest
val request = OpenRequest(
uri = documentUri,
displayName = displayName,
mimeType = "application/pdf",
)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.document_content, XReader.newFragment(request), "reader")
.commit()
}从业务标题栏触发搜索
import com.transsion.xreader.ReaderController
val controller = supportFragmentManager
.findFragmentByTag("reader") as? ReaderController
controller?.toggleSearch()
controller?.scrollToPage(3)页码从 0 开始。通过 ReaderController.state 观察加载、就绪与错误状态;只在页面生命周期有效时收集,不长期持有 Fragment 的 View。
04 / 使用独立阅读页面
将依赖替换为 ui(或 all),使用默认标题栏与搜索入口。阅读 Activity 运行在独立私有进程,业务页面保留在主进程。
import com.transsion.xreader.ui.ReaderActivityResultContract
import com.transsion.xreader.ui.ReaderAppearance
import com.transsion.xreader.ui.ReaderOutcome
private val readerLauncher = registerForActivityResult(
ReaderActivityResultContract(ReaderAppearance.SYSTEM),
) { result ->
when (result.outcome) {
ReaderOutcome.CLOSED -> saveReadingPosition(result.lastPage)
ReaderOutcome.DOCUMENT_ERROR -> showDocumentError(result.error)
ReaderOutcome.INTERRUPTED -> showRetryAction()
}
}
fun openPdf(request: OpenRequest) {
try {
readerLauncher.launch(request)
} catch (error: RuntimeException) {
showLaunchError()
}
}示例中的 saveReadingPosition、showDocumentError、showRetryAction、showLaunchError 由业务实现。系统可能重建阅读页面;INTERRUPTED 并非所有崩溃的即时通知。正常关闭时可以保存最后页码,中断时页码可能为空。
按进程划分应用初始化
override fun onCreate() {
super.onCreate()
if (Application.getProcessName() != applicationInfo.processName) return
initializeBusinessComponents()
}示例仅适用于这些组件只在主进程初始化的业务。已有其他进程时,应按各进程实际职责配置;业务单例和静态状态不会自动跨进程共享。
05 / 主题与外观
嵌入模式跟随宿主的 Light/Dark 和页面主题。独立页面通过 ReaderAppearance.SYSTEM、LIGHT 或 DARK 选择外观;主进程中的应用内夜间设置不会自动传到另一进程,需要显式传参。
外观适配影响背景、标题栏和搜索控件。PDF 页面保留文件原始颜色,不对内容做反色处理。
06 / 文件与权限
- 使用可读取的 content:// Uri;业务先下载远程文件,再交给 SDK。
- 系统文件选择器与 FileProvider 均可使用。SDK 不申请全盘存储或网络权限。
- 仅在来源授予持久读取权限时保存持久授权;分享接收的临时 Uri 需在授权有效期内读取。
- 独立页面通过 Intent 传递 Uri 和已有读取授权,不传整份 PDF 字节,也不凭空获得权限。
- 由业务决定是否注册 Android Open With。SDK 的默认 Activity 不向其他应用导出。
当前不提供密码输入与 OCR。密码文件会返回 PASSWORD_REQUIRED;不带文本层的扫描页可查看,但不支持内容搜索。
07 / 稳定性与范围
嵌入式阅读 UI 与业务同进程,未捕获的阅读 UI 异常可能影响业务。独立页面将阅读 UI 放入私有进程,降低这类故障直接影响主进程的风险;它与业务同 UID,不是安全沙箱。
系统对整应用的强制停止、整机内存压力,以及业务 Application 初始化或结果回调中的异常仍可能影响业务。请为实际设备、文件样本和生命周期场景安排接入验收,不将进程隔离理解为零崩溃保证。
建议验收内容
- 普通文本、图片、长文档、大文件、损坏文件和权限失效。
- 搜索、连续滑动、双指缩放、旋转、切后台与重新打开。
- Light/Dark、最低 Android 版本、低内存设备及业务 Release 混淆构建。
- 独立进程的启动耗时、内存峰值与业务初始化边界。
文档版本:2026-11-01 · 当前能力:Android PDF 阅读