本文首发地址 https://h89.cn/archives/493.html

前文分析了SVGA等动画的对比,但是SVGAPlayer(由 YY 团队开发)目前已归档(Public archive) ,今天我们来看看另外一种动画 PAG (Portable Animated Graphics) , 它是目前安卓开发中,替代 SVGA 和 Lottie 的最强方案,尤其是针对直播礼物、游戏特效、UI 复杂动效等场景。

它由 腾讯 (Tencent) 内部研发并开源,目前已经成为国内大厂(腾讯系、抖音、快手、B站等)的行业标准。

以下是对 PAG 的详细技术介绍,包括核心优势、工作原理以及与 SVGA/Lottie 的对比。


PAG 是什么?

PAG 是一套完整的动画工作流解决方案。它不仅仅是一个播放器,还包含了 AE (Adobe After Effects) 导出插件桌面预览工具多端 SDK(Android, iOS, Web, macOS, Windows)。

  • 核心逻辑: 它的底层是一个 C++ 编写的渲染引擎 (libpag),不依赖安卓原生的 Canvas 绘制指令(像 Lottie 那样),而是自己处理渲染管线。
  • 文件格式: .pag 文件是一种二进制格式,不像 Lottie/SVGA 是 JSON/文本格式。

为什么它是 SVGA 的最佳替代者?(核心优势)

相比于已归档的 SVGA 和通过 JSON 解析的 Lottie,PAG 解决了三个核心痛点:

  1. 极致的 AE 特性支持(设计师最爱)
  • 痛点: 以前用 Lottie/SVGA,设计师在 AE 里用了滤镜、遮罩、或者复杂的图层样式,导出来后发现安卓手机上显示效果不对,甚至直接崩了。
  • PAG 方案: PAG 支持几乎所有的 AE 特性。它甚至支持将 AE 的特效“烘焙”成位图序列与矢量混合。这意味着设计师在 AE 里看到什么样,手机上就一定是什么样
  1. 性能与解码速度(开发最爱)
  • 二进制文件: .pag 是二进制文件,解码速度比 JSON 快几十倍。
  • 单文件交付: SVGA 有时需要外挂图片资源,Lottie 也带有 img 文件夹。PAG 将所有图片、音频、矢量数据打包在一个文件里,且经过极高压缩。
  • GPU 加速: 深度利用 GPU 渲染,减轻 CPU 压力。
  1. 运行时编辑(直播/业务刚需)
    这是 PAG 最强大的功能,也是 SVGA 很难做到的:
  • 替换文本: 比如一个“火箭”礼物动画,你可以在代码里动态把火箭上的文字改成“感谢榜一大哥”。
  • 替换图片: 可以在动画播放过程中,把动画里的某个占位图替换成用户的实时头像

PAG vs Lottie vs SVGA 深度对比

维度 PAG (腾讯) Lottie (Airbnb) SVGA (YY - 已归档)
核心原理 C++ 引擎 + 二进制文件 原生 Canvas/Skia + JSON 原生 Canvas + Protobuf/Zlib
文件体积 ⭐⭐⭐⭐⭐ (极小) ⭐⭐⭐ (中等) ⭐⭐⭐ (中等,含位图较大)
性能消耗 ⭐⭐⭐⭐⭐ (极低) ⭐⭐⭐ (矢量复杂时高) ⭐⭐⭐ (一般,易内存泄漏)
AE 支持度 完美 (支持滤镜/特效) 一般 (受限于原生 API) 较差 (很多特效不支持)
动态替换 强大 (换字、换图、改色) 支持 (但代码复杂) 支持 (功能较弱)
稳定性 高 (大厂生产环境验证) (无人维护)
接入成本 中 (需引入 C++ so库) 低 (纯 Java/Kotlin)

Android 接入指南 (Kotlin)

  1. 添加依赖
    PAG 依赖 Native 库,会增加一点 APK 体积(约 3-4MB,视架构而定)。

    // app/build.gradle
    dependencies {
       implementation 'com.tencent.tav:libpag:4.5.2' // 建议去官网查最新版本
    }
    // 建议配置 ABI 过滤,避免引入全架构 SO 包导致体积过大
    android {
       defaultConfig {
           ndk {
               abiFilters 'armeabi-v7a', 'arm64-v8a'
           }
       }
    }
  2. 布局文件

    <org.libpag.PAGView
       android:id="@+id/pagView"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
  3. 播放动画

    val pagView = findViewById<PAGView>(R.id.pagView)
    // 1. 从 Assets 加载
    val pagFile = PAGFile.Load(assets, "gift_rocket.pag")
    // 2. 设置源并播放
    pagView.composition = pagFile
    pagView.setRepeatCount(0) // 0 不循环, -1 无限循环
    pagView.play()
  4. 高级功能 - 替换内容 (Runtime Editing)
    假设设计师在 AE 里给一个文本图层起名叫 username,给一个图片图层起名叫 avatar

  // 加载文件
  val pagFile = PAGFile.Load(assets, "gift.pag")

  // --- 1. 替换文本 ---
  // 找到所有叫 "username" 的文本图层并修改内容
  val textDataList = pagFile.getTextData(0) // 获取所有文本数据
  for (i in 0 until pagFile.numTexts()) {
      val textData = pagFile.getTextData(i)
      if (textData.layerName == "username") {
          textData.text = "张三"
          pagFile.replaceText(i, textData)
      }
  }

  // --- 2. 替换图片 (用户头像) ---
  // 将图层 "avatar" 替换为一个 Bitmap
  val myBitmap = BitmapFactory.decodeResource(resources, R.drawable.my_avatar)
  val pagImage = PAGImage.FromBitmap(myBitmap)
  pagFile.replaceImage(0, pagImage) // index 需根据图层索引查找,通常配合图层名查找

  // 应用修改并播放
  pagView.composition = pagFile
  pagView.play()

潜在缺点与注意事项

虽然 PAG 很好,但也有两个你需要考虑的“代价”:

  1. APK 体积增加:
    因为 PAG 底层是 C++ (libpag.so),不像 SVGAPlayer 是纯 Java。引入它会让你的 APK 增加 3MB - 5MB 左右的大小。如果你的 App 对包体大小极其敏感,需要权衡。
  2. 设计师的学习成本:
    设计师必须安装 PAG 的 AE 插件(虽然安装很简单),并且在导出时需要预览检查。如果设计师习惯了 Lottie 的 Bodymovin 插件,需要让他们适应新流程。

总结

如果你的安卓 App 需要替换 SVGAPlayer,且涉及直播礼物、复杂 UI 动效PAG 是目前唯一的、最完美的“版本答案”

  • 官网地址: pag.io (文档非常详细,有中文)
  • GitHub: Tencent/libpag

本文链接:Android动画详解PAG - https://h89.cn/archives/493.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: android, Lottie, svga, 动画, PAG

评论已关闭