<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>ListenerGao</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://www.listenergao.com/</id>
  <link href="https://www.listenergao.com/" rel="alternate"/>
  <link href="https://www.listenergao.com/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, ListenerGao</rights>
  <subtitle>ListenerGao 的个人博客</subtitle>
  <title>ListenerGao's Blog</title>
  <updated>2026-07-16T08:50:48.291Z</updated>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="工具" scheme="https://www.listenergao.com/categories/%E5%B7%A5%E5%85%B7/"/>
    <category term="效率工具" scheme="https://www.listenergao.com/tags/%E6%95%88%E7%8E%87%E5%B7%A5%E5%85%B7/"/>
    <content>
      <![CDATA[<p>因为把 <code>O0</code> 看混而 debug 半小时的痛，经历过一次就够了。一款好的等宽字体能明显降低读代码的疲劳度——<code>0</code> 和 <code>O</code>、<code>1</code> 和 <code>l</code> 和 <code>I</code> 清晰可辨是底线，连字（ligature）则是锦上添花。程序员折腾字体和折腾主题一样，属于「不能提升代码质量但能提升写代码心情」的刚需。这几款是我用过或长期关注的编程字体。</p><span id="more"></span><h2 id="1-FiraCode"><a href="#1-FiraCode" class="headerlink" title="1. FiraCode"></a>1. <a href="https://github.com/tonsky/FiraCode">FiraCode</a></h2><p>免费开源的等宽字体，最大特色是为常见编程多字符组合（<code>=&gt;</code>、<code>!=</code>、<code>&gt;=</code> 等）提供连字，视觉上更接近数学符号语义。第一次看到 <code>=&gt;</code> 变成一个真正的箭头，会有种「原来代码可以这么优雅」的错觉——错觉归错觉，看着是真舒服。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/11/16181298309455.jpg"></p><p>Mac 安装：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">brew install --cask font-fira-code<br></code></pre></td></tr></table></figure><h2 id="2-Menlo"><a href="#2-Menlo" class="headerlink" title="2. Menlo"></a>2. Menlo</h2><p>macOS 内建的无衬线等宽字体（Snow Leopard 起），由 Jim Lyles 设计，DejaVu Sans Mono 的衍生品，曾是 Xcode 的默认字体。系统自带，零配置。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/21/16189902425757.jpg"></p><h2 id="3-Source-Code-Pro"><a href="#3-Source-Code-Pro" class="headerlink" title="3. Source Code Pro"></a>3. <a href="https://github.com/adobe-fonts/source-code-pro">Source Code Pro</a></h2><p>Adobe 出品的开源编程字体，阅读体验出色，支持 Linux&#x2F;macOS&#x2F;Windows，商业和个人都免费。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/21/16189905224530.jpg"></p><h2 id="4-Monaco"><a href="#4-Monaco" class="headerlink" title="4. Monaco"></a>4. Monaco</h2><p>老 OS X 时代的默认等宽字体，浓浓的苹果风味，至今仍有大批拥趸。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/21/16189906028008.jpg"></p><h2 id="5-Hack"><a href="#5-Hack" class="headerlink" title="5. Hack"></a>5. <a href="https://github.com/source-foundry/Hack">Hack</a></h2><p>基于 Bitstream Vera 和 DejaVu 的开源字体，专为显示源代码设计，<code>0O</code>、<code>1lI</code> 辨识度极高。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/21/16189918889742.jpg"></p><p>Mac 安装：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">brew install --cask font-hack<br></code></pre></td></tr></table></figure><h2 id="6-Lucida-Sans-Typewriter"><a href="#6-Lucida-Sans-Typewriter" class="headerlink" title="6. Lucida Sans Typewriter"></a>6. Lucida Sans Typewriter</h2><p>高辨识度的经典等宽字体，字型干净大气，像打字机打出来的效果。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/21/16189921074158.jpg"></p><h2 id="7-Anonymous-Pro"><a href="#7-Anonymous-Pro" class="headerlink" title="7. Anonymous Pro"></a>7. Anonymous Pro</h2><p>复古打字机风格，中规中矩但各类字符辨识度高，对中文兼容性也不错。</p><p><img src="https://mweb-image-1258736741.cos.ap-beijing.myqcloud.com/2021/04/21/16189923437073.jpg"></p><hr><p>我的建议：想要连字选 <strong>FiraCode</strong>，懒得折腾用系统自带的 <strong>Menlo</strong>，追求辨识度选 <strong>Hack</strong>。当然，以我对程序员的了解，你大概率会全都装一遍、来回切换两周，最后用回第一个——这也是折腾的乐趣之一。</p>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/programming-fonts/</id>
    <link href="https://www.listenergao.com/2026/07/03/programming-fonts/"/>
    <published>2026-07-03T10:50:00.000Z</published>
    <summary>
      <![CDATA[<p>因为把 <code>O0</code> 看混而 debug 半小时的痛，经历过一次就够了。一款好的等宽字体能明显降低读代码的疲劳度——<code>0</code> 和 <code>O</code>、<code>1</code> 和 <code>l</code> 和 <code>I</code> 清晰可辨是底线，连字（ligature）则是锦上添花。程序员折腾字体和折腾主题一样，属于「不能提升代码质量但能提升写代码心情」的刚需。这几款是我用过或长期关注的编程字体。</p>]]>
    </summary>
    <title>程序员编程字体推荐</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="工具" scheme="https://www.listenergao.com/categories/%E5%B7%A5%E5%85%B7/"/>
    <category term="效率工具" scheme="https://www.listenergao.com/tags/%E6%95%88%E7%8E%87%E5%B7%A5%E5%85%B7/"/>
    <category term="Mac" scheme="https://www.listenergao.com/tags/Mac/"/>
    <content>
      <![CDATA[<p>新 Mac 到手的兴奋感，通常在打开空荡荡的启动台那一刻结束——「我原来都装了什么来着？」然后花一下午凭记忆碎片一个个找回来，还总觉得漏了什么（确实漏了，一周后你会想起来的）。</p><p>这篇就是为了终结这个轮回：我的 Mac 常备软件清单和 JDK 环境变量配置备忘，绝大部分免费或开源，照着装完直接开工。</p><span id="more"></span><h2 id="一、基础必装"><a href="#一、基础必装" class="headerlink" title="一、基础必装"></a>一、基础必装</h2><h3 id="Homebrew（开源免费）"><a href="#Homebrew（开源免费）" class="headerlink" title="Homebrew（开源免费）"></a><a href="https://brew.sh/index_zh-cn">Homebrew</a>（开源免费）</h3><p>macOS 的软件包管理工具，后面很多软件都通过它一行命令安装。主要由 brew、homebrew-core（核心源）、homebrew-cask（macOS 应用和大型二进制）、homebrew-bottles（预编译包）组成。国内建议配置镜像源，可参考<a href="https://zhuanlan.zhihu.com/p/90508170">这篇安装教程</a>。</p><h3 id="iTerm2（开源免费）"><a href="#iTerm2（开源免费）" class="headerlink" title="iTerm2（开源免费）"></a><a href="https://iterm2.com/">iTerm2</a>（开源免费）</h3><p>Mac 下最好用的终端，替代系统自带 Terminal：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">brew install --cask iterm2<br></code></pre></td></tr></table></figure><p>建议配合 oh-my-zsh 使用，教程网上很多。</p><h3 id="Alfred（部分功能收费）"><a href="#Alfred（部分功能收费）" class="headerlink" title="Alfred（部分功能收费）"></a><a href="https://www.alfredapp.com/">Alfred</a>（部分功能收费）</h3><p>Mac 效率神器：手不离键盘完成打开 App、搜文件、搜网页、自定义 workflow、剪贴板管理等所有操作，Spotlight 的完全上位替代——用熟之后再摸鼠标会有一种莫名的挫败感。免费版功能已经够用，进阶玩法可参考 <a href="https://juejin.cn/post/6844904062484217863">高效 Alfred 进阶</a>。</p><h2 id="二、开发相关"><a href="#二、开发相关" class="headerlink" title="二、开发相关"></a>二、开发相关</h2><h3 id="draw-io（免费）"><a href="#draw-io（免费）" class="headerlink" title="draw.io（免费）"></a><a href="https://drawio-app.com/">draw.io</a>（免费）</h3><p>强大简洁的绘图工具：流程图、UML、架构图、原型图全支持，可同步 GitHub&#x2F;Google Drive，支持<a href="http://draw.io/">在线编辑</a>，也有离线桌面版。</p><h3 id="scrcpy（开源免费）"><a href="#scrcpy（开源免费）" class="headerlink" title="scrcpy（开源免费）"></a><a href="https://github.com/Genymobile/scrcpy/blob/master/README.zh-Hans.md">scrcpy</a>（开源免费）</h3><p>USB&#x2F;TCP 连接即可在电脑上显示并控制 Android 设备，不需要 root，支持 Linux&#x2F;Windows&#x2F;macOS。Android 开发调试和录屏演示利器。</p><h2 id="三、状态栏与系统监控"><a href="#三、状态栏与系统监控" class="headerlink" title="三、状态栏与系统监控"></a>三、状态栏与系统监控</h2><ul><li><a href="https://bjango.com/mac/istatmenus/"><strong>iStat Menus</strong></a>（收费）：最优秀的系统监控工具，菜单栏实时显示 CPU、GPU、内存、硬盘、网络、温度、电池，稳定且占用低。</li><li><a href="https://github.com/gao-sun/eul"><strong>eul</strong></a>（开源免费）：SwiftUI 编写的菜单栏监控，iStat Menus 的免费替代：<code>brew install --cask eul</code></li><li><a href="https://apps.apple.com/cn/app/id1472818562?mt=12"><strong>State</strong></a>（免费）：App Store 直接装的系统状态监控。</li><li><a href="https://apps.apple.com/cn/app/id6443843900?mt=12"><strong>iBar</strong></a>（免费，Pro 收费）：菜单栏图标管理，图标太多时一键收纳，刘海屏 Mac 体验提升明显。</li></ul><h2 id="四、截图工具"><a href="#四、截图工具" class="headerlink" title="四、截图工具"></a>四、截图工具</h2><ul><li><a href="https://zh.snipaste.com/"><strong>Snipaste</strong></a>：简单强大的截图 + 贴图工具。「贴图」是杀手级功能——把设计稿截图钉在屏幕上对照写 UI，比在两个窗口间 Cmd+Tab 切到手抽筋文明多了：<code>brew install --cask snipaste</code></li><li><a href="https://www.better365.com/ishot.html"><strong>iShot</strong></a>：截图、长截图、带壳截图、标注、取色、录屏、录音、OCR、翻译，一个顶十个。</li></ul><h2 id="五、其他"><a href="#五、其他" class="headerlink" title="五、其他"></a>五、其他</h2><ul><li><a href="https://apps.apple.com/cn/app/id1551462255?mt=12"><strong>右键助手</strong></a>（部分收费）：给访达右键菜单加 30 多种小工具（新建文件、拷贝路径、快速移动等）。</li></ul><h2 id="附：Mac-配置-JDK-环境变量"><a href="#附：Mac-配置-JDK-环境变量" class="headerlink" title="附：Mac 配置 JDK 环境变量"></a>附：Mac 配置 JDK 环境变量</h2><p>JDK 各版本下载：<a href="https://www.oracle.com/cn/java/technologies/downloads/archive/">Oracle Archive</a>。安装路径默认在 <code>/Library/Java/JavaVirtualMachines/</code>，如 JDK8：<code>/Library/Java/JavaVirtualMachines/jdk1.8.0_341.jdk/Contents/Home</code>。</p><p>macOS Catalina 之后默认 shell 是 zsh，配置写进 <code>~/.zshrc</code>（老系统用 bash 的话写 <code>~/.bash_profile</code>——对着 <code>.bash_profile</code> 改半天却不生效的朋友，先看看自己的 shell 是谁）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 安装单个 JDK 版本</span><br><span class="hljs-built_in">export</span> JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_341.jdk/Contents/Home<br><br><span class="hljs-comment"># 安装多个 JDK 版本时，可以做成别名一键切换</span><br><span class="hljs-built_in">export</span> JAVA_7_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home<br><span class="hljs-built_in">export</span> JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_341.jdk/Contents/Home<br><br><span class="hljs-built_in">alias</span> jdk7=<span class="hljs-string">&quot;export JAVA_HOME=<span class="hljs-variable">$JAVA_7_HOME</span>&quot;</span>   <span class="hljs-comment"># 输入 jdk7 切换到 JDK 1.7</span><br><span class="hljs-built_in">alias</span> jdk8=<span class="hljs-string">&quot;export JAVA_HOME=<span class="hljs-variable">$JAVA_8_HOME</span>&quot;</span>   <span class="hljs-comment"># 输入 jdk8 切换到 JDK 1.8</span><br><br><span class="hljs-comment"># 默认指向系统里最新的 JDK 版本</span><br><span class="hljs-built_in">export</span> JAVA_HOME=`/usr/libexec/java_home`<br></code></pre></td></tr></table></figure><p>改完执行 <code>source ~/.zshrc</code> 生效，<code>java -version</code> 验证。</p>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/mac-dev-setup/</id>
    <link href="https://www.listenergao.com/2026/07/03/mac-dev-setup/"/>
    <published>2026-07-03T10:40:00.000Z</published>
    <summary>
      <![CDATA[<p>新 Mac 到手的兴奋感，通常在打开空荡荡的启动台那一刻结束——「我原来都装了什么来着？」然后花一下午凭记忆碎片一个个找回来，还总觉得漏了什么（确实漏了，一周后你会想起来的）。</p>
<p>这篇就是为了终结这个轮回：我的 Mac 常备软件清单和 JDK 环境变量配置备忘，绝大部分免费或开源，照着装完直接开工。</p>]]>
    </summary>
    <title>我的 Mac 软件清单与开发环境配置</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="Android" scheme="https://www.listenergao.com/categories/Android/"/>
    <category term="Android" scheme="https://www.listenergao.com/tags/Android/"/>
    <content>
      <![CDATA[<p>程序员的效率提升，一半靠新键盘（心理作用），另一半靠一套顺手的工具链（真实作用）。这篇整理我在 Android 开发中沉淀下来的三类效率工具：开箱即用的第三方库、Android Studio 插件、以及国内构建提速必备的 Maven 镜像源——最后这个能治好你「一杯茶一包烟，一个 Gradle sync 一天」的顽疾。</p><span id="more"></span><h2 id="一、常用第三方库"><a href="#一、常用第三方库" class="headerlink" title="一、常用第三方库"></a>一、常用第三方库</h2><h3 id="UI-整体方案"><a href="#UI-整体方案" class="headerlink" title="UI 整体方案"></a>UI 整体方案</h3><ul><li><a href="https://github.com/xuexiangjys/XUI/blob/master/README_ZH.md"><strong>XUI</strong></a>：简洁优雅的 Android 原生 UI 框架。注意它给出的是一整套 UI 解决方案，如果只想用其中几个控件，没必要引入这么庞大的库。</li><li><a href="https://github.com/Tencent/QMUI_Android"><strong>QMUI_Android</strong></a>：腾讯出品，辅助快速搭建具备基本设计还原效果的项目，丰富控件 + 兼容处理，让开发者专注业务。</li></ul><h3 id="单点控件"><a href="#单点控件" class="headerlink" title="单点控件"></a>单点控件</h3><ul><li><a href="https://github.com/rengwuxian/MaterialEditText"><strong>MaterialEditText</strong></a>：符合 Material Design 规范的 EditText。</li><li><a href="https://github.com/razerdp/BasePopup"><strong>BasePopup</strong></a>：对系统 PopupWindow 封装改进的弹窗库，自由度和 API 丰富度都很高。</li><li><a href="https://github.com/angcyo/DslTabLayout"><strong>DslTabLayout</strong></a>：号称 Android 界最万能的 TabLayout，高能自绘控件，继承自 ViewGroup 而非组合控件。</li><li><a href="https://github.com/scwang90/SmartRefreshLayout"><strong>SmartRefreshLayout</strong></a>：强大稳定的下拉刷新框架，支持所有 View 和多层嵌套结构，集成了各种炫酷的 Header&#x2F;Footer。</li></ul><h3 id="选择器"><a href="#选择器" class="headerlink" title="选择器"></a>选择器</h3><ul><li><a href="https://github.com/gzu-liyujiang/AndroidPicker"><strong>AndroidPicker</strong></a>：日期时间、单项、二三级联动、城市地址、数字、日历、颜色、文件目录选择器，一库全包。</li><li><a href="https://github.com/LuckSiege/PictureSelector/blob/version_component/README_CN.md"><strong>PictureSelector</strong></a>：图片&#x2F;视频&#x2F;音频选择器，支持拍照、裁剪、压缩、权限适配。</li><li><a href="https://github.com/xuexiangjys/CityPicker"><strong>CityPicker</strong></a>：美团外卖式的城市选择界面，一行代码接入。</li></ul><h3 id="WebView-与权限"><a href="#WebView-与权限" class="headerlink" title="WebView 与权限"></a>WebView 与权限</h3><ul><li><a href="https://github.com/Justson/AgentWeb"><strong>AgentWeb</strong></a>：极易使用且功能强大的 WebView 库，解决了 Android WebView 的一系列坑。</li><li><a href="https://github.com/getActivity/XXPermissions"><strong>XXPermissions</strong></a>：权限请求框架，长期维护、系统适配及时。</li></ul><h3 id="网络框架"><a href="#网络框架" class="headerlink" title="网络框架"></a>网络框架</h3><ul><li><a href="https://github.com/square/okhttp"><strong>OkHttp</strong></a> &#x2F; <a href="https://github.com/square/retrofit"><strong>Retrofit</strong></a>：事实标准，不用介绍——没用过的 Android 开发者建议假装用过。</li><li><a href="https://github.com/liujingxing/rxhttp/blob/master/README_zh.md"><strong>RxHttp</strong></a>、<a href="https://github.com/liangjingkanji/Net"><strong>Net</strong></a>、<a href="https://github.com/getActivity/EasyHttp"><strong>EasyHttp</strong></a>：国产封装，链式 API 更顺手，按团队口味选。</li></ul><h2 id="二、Android-Studio-插件"><a href="#二、Android-Studio-插件" class="headerlink" title="二、Android Studio 插件"></a>二、Android Studio 插件</h2><ul><li><a href="https://github.com/YiiGuxing/TranslationPlugin"><strong>Translation</strong></a>：强大的 IDE 翻译插件，支持 Google&#x2F;有道&#x2F;百度等翻译引擎，IDE 插件市场直接搜 “Translation” 安装。</li><li><a href="https://github.com/Vektah/CodeGlance"><strong>CodeGlance</strong></a>：编辑器右侧的代码缩略图，类似 Sublime 的 minimap，长文件快速定位。</li><li><a href="https://github.com/mistamek/Android-drawable-preview-plugin"><strong>Android Drawable Preview</strong></a>：在项目树里直接预览 drawable 图标。</li><li><a href="https://github.com/wuseal/JsonToKotlinClass"><strong>JsonToKotlinClass</strong></a>：JSON 字符串一键转 Kotlin data class。</li><li><a href="https://wakatime.com/dashboard"><strong>WakaTime</strong></a>：编码时间统计工具，支持主流 IDE 和 Chrome。注册账号 → 装插件 → 填 Secret API Key，就能在网站上看到自己的编码报告。</li></ul><h2 id="三、Maven-镜像源（国内构建提速）"><a href="#三、Maven-镜像源（国内构建提速）" class="headerlink" title="三、Maven 镜像源（国内构建提速）"></a>三、Maven 镜像源（国内构建提速）</h2><p>Gradle sync 转圈转到怀疑人生，八成不是你网速的问题，是仓库在地球另一边。阿里云的镜像仓库是目前最省心的方案（<a href="https://developer.aliyun.com/mvn/view">阿里云云效 Maven</a>）：</p><table><thead><tr><th align="left">仓库</th><th align="left">源地址</th><th align="left">阿里云镜像</th></tr></thead><tbody><tr><td align="left">mavenCentral</td><td align="left"><a href="https://repo1.maven.org/maven2">https://repo1.maven.org/maven2</a></td><td align="left"><a href="https://maven.aliyun.com/repository/central">https://maven.aliyun.com/repository/central</a></td></tr><tr><td align="left">google</td><td align="left"><a href="https://maven.google.com/">https://maven.google.com</a></td><td align="left"><a href="https://maven.aliyun.com/repository/google">https://maven.aliyun.com/repository/google</a></td></tr><tr><td align="left">gradle-plugin</td><td align="left"><a href="https://plugins.gradle.org/m2">https://plugins.gradle.org/m2</a></td><td align="left"><a href="https://maven.aliyun.com/repository/gradle-plugin">https://maven.aliyun.com/repository/gradle-plugin</a></td></tr><tr><td align="left">jcenter（已废弃）</td><td align="left"><a href="http://jcenter.bintray.com/">http://jcenter.bintray.com</a></td><td align="left"><a href="https://maven.aliyun.com/repository/jcenter">https://maven.aliyun.com/repository/jcenter</a></td></tr><tr><td align="left">public（central+jcenter 聚合）</td><td align="left">—</td><td align="left"><a href="https://maven.aliyun.com/repository/public">https://maven.aliyun.com/repository/public</a></td></tr><tr><td align="left">jitpack</td><td align="left"><a href="https://jitpack.io/">https://jitpack.io</a></td><td align="left"><a href="https://jitpack.io/">https://jitpack.io</a></td></tr></tbody></table><p>jcenter 已经作古，老项目里还有依赖走 jcenter 的，尽快迁到 mavenCentral 或用阿里云镜像兜底——别等哪天全量构建失败了才想起这条。</p>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/android-dev-toolbox/</id>
    <link href="https://www.listenergao.com/2026/07/03/android-dev-toolbox/"/>
    <published>2026-07-03T10:30:00.000Z</published>
    <summary>
      <![CDATA[<p>程序员的效率提升，一半靠新键盘（心理作用），另一半靠一套顺手的工具链（真实作用）。这篇整理我在 Android 开发中沉淀下来的三类效率工具：开箱即用的第三方库、Android Studio 插件、以及国内构建提速必备的 Maven 镜像源——最后这个能治好你「一杯茶一包烟，一个 Gradle sync 一天」的顽疾。</p>]]>
    </summary>
    <title>Android 开发效率工具箱：常用库、插件与镜像源</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="Android" scheme="https://www.listenergao.com/categories/Android/"/>
    <category term="Android" scheme="https://www.listenergao.com/tags/Android/"/>
    <category term="adb" scheme="https://www.listenergao.com/tags/adb/"/>
    <content>
      <![CDATA[<p>做 Android 开发这些年，adb 大概是我敲得最多的三个字母（没有之一，git 表示不服）。命令大全网上一搜一大把，但真到用的时候还是想不起来参数怎么拼——所以这篇只收录我日常真正高频使用的命令，按场景分类，忘了就回来抄。想要百科全书版的，推荐 <a href="https://github.com/mzlogin/awesome-adb">mzlogin&#x2F;awesome-adb</a>，本文的整理也参考了该项目。</p><span id="more"></span><h2 id="一、设备连接"><a href="#一、设备连接" class="headerlink" title="一、设备连接"></a>一、设备连接</h2><p><strong>USB 连接</strong>：设备开启「开发者选项 → USB 调试」，连线后确认：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb devices        <span class="hljs-comment"># 列出已连接设备</span><br></code></pre></td></tr></table></figure><p><strong>WiFi 连接</strong>（初次需借助 USB 线）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb tcpip 5555                    <span class="hljs-comment"># 让设备在 5555 端口监听 TCP/IP 连接</span><br>adb connect &lt;device-ip&gt;           <span class="hljs-comment"># 断开 USB 后用设备 IP 连接（IP 在设置-关于手机里查）</span><br>adb disconnect &lt;device-ip&gt;        <span class="hljs-comment"># 用完断开</span><br></code></pre></td></tr></table></figure><p>多设备并存时用 <code>-s</code> 指定目标设备：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb -s emulator-5554 shell<br></code></pre></td></tr></table></figure><h2 id="二、应用管理"><a href="#二、应用管理" class="headerlink" title="二、应用管理"></a>二、应用管理</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb install -r demo.apk                   <span class="hljs-comment"># 安装（-r 允许覆盖安装，-t 允许装 debug 包，-d 允许降级）</span><br>adb uninstall &lt;package&gt;                   <span class="hljs-comment"># 卸载（-k 保留数据和缓存）</span><br>adb shell pm clear &lt;package&gt;              <span class="hljs-comment"># 清除应用数据与缓存（等于设置里点「清除数据」）</span><br>adb shell am force-stop &lt;package&gt;         <span class="hljs-comment"># 强制停止应用</span><br>adb shell pm list packages -3             <span class="hljs-comment"># 列出第三方应用包名（-s 系统应用，无参数为全部）</span><br>adb shell pm list packages &lt;keyword&gt;      <span class="hljs-comment"># 按关键字过滤包名</span><br>adb shell pm path &lt;package&gt;               <span class="hljs-comment"># 查看应用安装路径</span><br>adb shell dumpsys package &lt;package&gt;       <span class="hljs-comment"># 查看应用详细信息（版本、权限、签名等）</span><br></code></pre></td></tr></table></figure><p>安装失败时控制台会甩给你一串大写的错误码，看着吓人，其实翻译过来大多是「你装过了」「签名不对」「先卸载」这三句话的排列组合。常见的几个：</p><table><thead><tr><th align="left">错误码</th><th align="left">原因</th><th align="left">解决</th></tr></thead><tbody><tr><td align="left">INSTALL_FAILED_ALREADY_EXISTS</td><td align="left">应用已存在</td><td align="left">加 <code>-r</code> 或先卸载</td></tr><tr><td align="left">INSTALL_FAILED_UPDATE_INCOMPATIBLE</td><td align="left">已装同名应用但签名不一致</td><td align="left">先卸载再装</td></tr><tr><td align="left">INSTALL_FAILED_VERSION_DOWNGRADE</td><td align="left">已安装更高版本</td><td align="left">加 <code>-d</code></td></tr><tr><td align="left">INSTALL_FAILED_TEST_ONLY</td><td align="left">Android Studio 直接 Run 出来的包</td><td align="left">用 assembleDebug 重新打包，或加 <code>-t</code></td></tr><tr><td align="left">INSTALL_FAILED_INSUFFICIENT_STORAGE</td><td align="left">存储空间不足</td><td align="left">清理空间</td></tr></tbody></table><h2 id="三、实战：从手机提取已安装应用的-APK"><a href="#三、实战：从手机提取已安装应用的-APK" class="headerlink" title="三、实战：从手机提取已安装应用的 APK"></a>三、实战：从手机提取已安装应用的 APK</h2><p>「这个 App 的效果怎么实现的？」——想反编译研究一下，第一步得先把 APK 弄下来。这是我用得最多的组合技之一：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb shell pm list packages | grep &lt;关键字&gt;     <span class="hljs-comment"># 1. 找到目标应用包名（也可用 LibChecker 查）</span><br>adb shell pm path com.tencent.mobileqq         <span class="hljs-comment"># 2. 获取安装路径</span><br>adb pull /data/app/&lt;path&gt;/base.apk ~/Desktop/  <span class="hljs-comment"># 3. 拉取 APK 到电脑</span><br></code></pre></td></tr></table></figure><h2 id="四、日志"><a href="#四、日志" class="headerlink" title="四、日志"></a>四、日志</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb logcat                                <span class="hljs-comment"># 全部日志</span><br>adb logcat -s TagName                     <span class="hljs-comment"># 只看指定 tag</span><br>adb logcat <span class="hljs-string">&#x27;*:W&#x27;</span>                          <span class="hljs-comment"># 按级别过滤（V/D/I/W/E/F/S 依次升高；macOS 下要加引号）</span><br>adb logcat ActivityManager:I MyApp:D <span class="hljs-string">&#x27;*:S&#x27;</span>  <span class="hljs-comment"># 组合过滤：指定 tag 的指定级别，屏蔽其它</span><br>adb logcat -v <span class="hljs-keyword">time</span>                        <span class="hljs-comment"># 输出格式带时间戳（可选 brief/tag/time/threadtime/long 等）</span><br>adb logcat -c                             <span class="hljs-comment"># 清空日志缓冲区</span><br>adb logcat &gt; log.txt                      <span class="hljs-comment"># 输出到文件</span><br>adb wait-for-device logcat -b all -v <span class="hljs-keyword">time</span> &gt; log.txt   <span class="hljs-comment"># 设备一连上就自动开抓，抓全部缓冲区</span><br>adb shell dmesg                           <span class="hljs-comment"># 内核日志</span><br></code></pre></td></tr></table></figure><h2 id="五、模拟按键与输入"><a href="#五、模拟按键与输入" class="headerlink" title="五、模拟按键与输入"></a>五、模拟按键与输入</h2><p><code>adb shell input</code> 在自动化和调试时非常好用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb shell input keyevent 3                <span class="hljs-comment"># HOME 键</span><br>adb shell input keyevent 4                <span class="hljs-comment"># 返回键</span><br>adb shell input keyevent 26               <span class="hljs-comment"># 电源键</span><br>adb shell input keyevent 82               <span class="hljs-comment"># 菜单键</span><br>adb shell input keyevent 24               <span class="hljs-comment"># 音量加（25 减，164 静音）</span><br>adb shell input text hello_world          <span class="hljs-comment"># 向焦点文本框输入文本</span><br>adb shell input tap 500 800               <span class="hljs-comment"># 点击坐标</span><br>adb shell input swipe 300 1000 300 500    <span class="hljs-comment"># 滑动（可加持续时间 ms）</span><br></code></pre></td></tr></table></figure><p>完整 keycode 列表见 <a href="https://developer.android.com/reference/android/view/KeyEvent.html">KeyEvent 文档</a>。</p><h2 id="六、截图与录屏"><a href="#六、截图与录屏" class="headerlink" title="六、截图与录屏"></a>六、截图与录屏</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb exec-out screencap -p &gt; sc.png              <span class="hljs-comment"># 截图直接保存到电脑</span><br>adb shell screenrecord /sdcard/demo.mp4         <span class="hljs-comment"># 录屏（Ctrl-C 停止，默认最长 180 秒）</span><br>adb shell screenrecord --size 1280x720 --bit-rate 6000000 --time-limit 30 /sdcard/demo.mp4<br>adb pull /sdcard/demo.mp4                       <span class="hljs-comment"># 导出到电脑</span><br></code></pre></td></tr></table></figure><h2 id="七、设备信息"><a href="#七、设备信息" class="headerlink" title="七、设备信息"></a>七、设备信息</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb shell getprop ro.build.version.release   <span class="hljs-comment"># 系统版本</span><br>adb shell getprop ro.build.version.sdk       <span class="hljs-comment"># SDK 版本</span><br>adb shell getprop ro.product.model           <span class="hljs-comment"># 设备型号</span><br>adb shell getprop ro.product.brand           <span class="hljs-comment"># 厂商</span><br>adb shell wm size                            <span class="hljs-comment"># 屏幕分辨率</span><br>adb shell wm density                         <span class="hljs-comment"># 屏幕密度</span><br>adb shell dumpsys battery                    <span class="hljs-comment"># 电池状态（level 为当前电量）</span><br>adb shell settings get secure android_id     <span class="hljs-comment"># android_id</span><br>adb shell <span class="hljs-built_in">cat</span> /proc/cpuinfo                  <span class="hljs-comment"># CPU 信息</span><br>adb shell <span class="hljs-built_in">cat</span> /proc/meminfo                  <span class="hljs-comment"># 内存信息</span><br>adb shell ifconfig wlan0                     <span class="hljs-comment"># WiFi IP 地址</span><br></code></pre></td></tr></table></figure><h2 id="八、文件传输"><a href="#八、文件传输" class="headerlink" title="八、文件传输"></a>八、文件传输</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb push &lt;本地路径&gt; &lt;设备路径&gt;     <span class="hljs-comment"># 电脑 → 设备</span><br>adb pull &lt;设备路径&gt; [本地路径]     <span class="hljs-comment"># 设备 → 电脑，本地路径省略则存到当前目录</span><br></code></pre></td></tr></table></figure><h2 id="九、与应用交互（am-命令）"><a href="#九、与应用交互（am-命令）" class="headerlink" title="九、与应用交互（am 命令）"></a>九、与应用交互（am 命令）</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb shell am start -a android.settings.SETTINGS                <span class="hljs-comment"># 打开系统设置</span><br>adb shell am start -a android.intent.action.DIAL -d tel:10086  <span class="hljs-comment"># 打开拨号页</span><br>adb shell am start -n &lt;package&gt;/&lt;activity&gt;                     <span class="hljs-comment"># 启动指定 Activity</span><br>adb shell am start -W -n &lt;package&gt;/&lt;activity&gt;                  <span class="hljs-comment"># 启动并等待完成（测启动耗时）</span><br>adb shell am broadcast -a &lt;action&gt;                             <span class="hljs-comment"># 发送广播（制造难复现的广播场景很实用）</span><br></code></pre></td></tr></table></figure><h2 id="十、修改设备设置（调试适配利器）"><a href="#十、修改设备设置（调试适配利器）" class="headerlink" title="十、修改设备设置（调试适配利器）"></a>十、修改设备设置（调试适配利器）</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb shell wm size 480x1024        <span class="hljs-comment"># 临时修改分辨率（测小屏适配）</span><br>adb shell wm size reset           <span class="hljs-comment"># 恢复</span><br>adb shell wm density 160          <span class="hljs-comment"># 临时修改屏幕密度</span><br>adb shell wm density reset        <span class="hljs-comment"># 恢复</span><br></code></pre></td></tr></table></figure><h2 id="十一、其他"><a href="#十一、其他" class="headerlink" title="十一、其他"></a>十一、其他</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb reboot                        <span class="hljs-comment"># 重启设备</span><br>adb reboot recovery               <span class="hljs-comment"># 重启到 Recovery 模式</span><br>adb reboot bootloader             <span class="hljs-comment"># 重启到 Fastboot 模式</span><br>adb shell monkey -p &lt;package&gt; -v 500   <span class="hljs-comment"># Monkey 随机事件压力测试（让猴子帮你乱点 500 下）</span><br>adb kill-server &amp;&amp; adb start-server    <span class="hljs-comment"># adb 抽风时的重启大法，成功率高得离谱</span><br></code></pre></td></tr></table></figure><hr><p><strong>参考</strong>：<a href="https://github.com/mzlogin/awesome-adb">mzlogin&#x2F;awesome-adb</a>——最全面的 adb 命令中文文档，本文按个人使用频率做了精选和场景化整理。</p>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/adb-cheatsheet/</id>
    <link href="https://www.listenergao.com/2026/07/03/adb-cheatsheet/"/>
    <published>2026-07-03T10:20:00.000Z</published>
    <summary>
      <![CDATA[<p>做 Android 开发这些年，adb 大概是我敲得最多的三个字母（没有之一，git 表示不服）。命令大全网上一搜一大把，但真到用的时候还是想不起来参数怎么拼——所以这篇只收录我日常真正高频使用的命令，按场景分类，忘了就回来抄。想要百科全书版的，推荐 <a href="https://github.com/mzlogin/awesome-adb">mzlogin&#x2F;awesome-adb</a>，本文的整理也参考了该项目。</p>]]>
    </summary>
    <title>我常用的 adb 命令速查</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="Android" scheme="https://www.listenergao.com/categories/Android/"/>
    <category term="Android" scheme="https://www.listenergao.com/tags/Android/"/>
    <content>
      <![CDATA[<p>设计师：”这里用 #FFFFFF，透明度 40%。”<br>你：（打开计算器，陷入沉思）</p><p>这个场景每个 Android 开发者都不陌生——标注图上颜色是 RGB、透明度却是百分比，而代码里要的是 <code>#AARRGGBB</code>。这篇就是那张让你告别心算的百分比 ↔ 十六进制对照表：40% 透明度的白色，就是 <code>#99FFFFFF</code>，抄走。</p><span id="more"></span><h2 id="颜色值格式"><a href="#颜色值格式" class="headerlink" title="颜色值格式"></a>颜色值格式</h2><p>Android 中的颜色值遵循 RGB&#x2F;ARGB 标准，以 <code>#</code> 开头、16 进制表示，常用格式：</p><table><thead><tr><th align="center">序号</th><th align="center">格式</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">#RGB</td></tr><tr><td align="center">2</td><td align="center">#ARGB</td></tr><tr><td align="center">3</td><td align="center">#RRGGBB</td></tr><tr><td align="center">4</td><td align="center">#AARRGGBB</td></tr></tbody></table><p>ARGB 依次代表透明度（alpha）、红色（red）、绿色（green）、蓝色（blue）。以 <code>#FF99CC00</code> 为例：FF 是透明度，99 是红色值，CC 是绿色值，00 是蓝色值。</p><h2 id="透明度与不透明度"><a href="#透明度与不透明度" class="headerlink" title="透明度与不透明度"></a>透明度与不透明度</h2><p>透明度分为 256 阶（0-255），16 进制表示为 00-FF。<strong>这里有个最容易翻车的点：ARGB 中的 alpha 表示的是「不透明度」</strong>——透明度和不透明度是一对冤家，加起来正好 100%。所以标注图说「透明度 40%」，得先换算成不透明度 60%，再查表得到 <code>99</code>。直接拿 40% 去查表，颜色效果就和设计稿反着来，然后就是一轮「你改了吗」「我改了呀」的经典对线。</p><h2 id="对照表"><a href="#对照表" class="headerlink" title="对照表"></a>对照表</h2><table><thead><tr><th align="center">不透明度</th><th align="center">十六进制</th><th align="center">不透明度</th><th align="center">十六进制</th><th align="center">不透明度</th><th align="center">十六进制</th><th align="center">不透明度</th><th align="center">十六进制</th></tr></thead><tbody><tr><td align="center">100%</td><td align="center">FF</td><td align="center">75%</td><td align="center">BF</td><td align="center">50%</td><td align="center">80</td><td align="center">25%</td><td align="center">40</td></tr><tr><td align="center">99%</td><td align="center">FC</td><td align="center">74%</td><td align="center">BD</td><td align="center">49%</td><td align="center">7D</td><td align="center">24%</td><td align="center">3D</td></tr><tr><td align="center">98%</td><td align="center">FA</td><td align="center">73%</td><td align="center">BA</td><td align="center">48%</td><td align="center">7A</td><td align="center">23%</td><td align="center">3B</td></tr><tr><td align="center">97%</td><td align="center">F7</td><td align="center">72%</td><td align="center">B8</td><td align="center">47%</td><td align="center">78</td><td align="center">22%</td><td align="center">38</td></tr><tr><td align="center">96%</td><td align="center">F5</td><td align="center">71%</td><td align="center">B5</td><td align="center">46%</td><td align="center">75</td><td align="center">21%</td><td align="center">36</td></tr><tr><td align="center">95%</td><td align="center">F2</td><td align="center">70%</td><td align="center">B3</td><td align="center">45%</td><td align="center">73</td><td align="center">20%</td><td align="center">33</td></tr><tr><td align="center">94%</td><td align="center">F0</td><td align="center">69%</td><td align="center">B0</td><td align="center">44%</td><td align="center">70</td><td align="center">19%</td><td align="center">30</td></tr><tr><td align="center">93%</td><td align="center">ED</td><td align="center">68%</td><td align="center">AD</td><td align="center">43%</td><td align="center">6E</td><td align="center">18%</td><td align="center">2E</td></tr><tr><td align="center">92%</td><td align="center">EB</td><td align="center">67%</td><td align="center">AB</td><td align="center">42%</td><td align="center">6B</td><td align="center">17%</td><td align="center">2B</td></tr><tr><td align="center">91%</td><td align="center">E8</td><td align="center">66%</td><td align="center">A8</td><td align="center">41%</td><td align="center">69</td><td align="center">16%</td><td align="center">29</td></tr><tr><td align="center">90%</td><td align="center">E6</td><td align="center">65%</td><td align="center">A6</td><td align="center">40%</td><td align="center">66</td><td align="center">15%</td><td align="center">26</td></tr><tr><td align="center">89%</td><td align="center">E3</td><td align="center">64%</td><td align="center">A3</td><td align="center">39%</td><td align="center">63</td><td align="center">14%</td><td align="center">24</td></tr><tr><td align="center">88%</td><td align="center">E0</td><td align="center">63%</td><td align="center">A1</td><td align="center">38%</td><td align="center">61</td><td align="center">13%</td><td align="center">21</td></tr><tr><td align="center">87%</td><td align="center">DE</td><td align="center">62%</td><td align="center">9E</td><td align="center">37%</td><td align="center">5E</td><td align="center">12%</td><td align="center">1F</td></tr><tr><td align="center">86%</td><td align="center">DB</td><td align="center">61%</td><td align="center">9C</td><td align="center">36%</td><td align="center">5C</td><td align="center">11%</td><td align="center">1C</td></tr><tr><td align="center">85%</td><td align="center">D9</td><td align="center">60%</td><td align="center">99</td><td align="center">35%</td><td align="center">59</td><td align="center">10%</td><td align="center">1A</td></tr><tr><td align="center">84%</td><td align="center">D6</td><td align="center">59%</td><td align="center">96</td><td align="center">34%</td><td align="center">57</td><td align="center">9%</td><td align="center">17</td></tr><tr><td align="center">83%</td><td align="center">D4</td><td align="center">58%</td><td align="center">94</td><td align="center">33%</td><td align="center">54</td><td align="center">8%</td><td align="center">14</td></tr><tr><td align="center">82%</td><td align="center">D1</td><td align="center">57%</td><td align="center">91</td><td align="center">32%</td><td align="center">52</td><td align="center">7%</td><td align="center">12</td></tr><tr><td align="center">81%</td><td align="center">CF</td><td align="center">56%</td><td align="center">8F</td><td align="center">31%</td><td align="center">4F</td><td align="center">6%</td><td align="center">0F</td></tr><tr><td align="center">80%</td><td align="center">CC</td><td align="center">55%</td><td align="center">8C</td><td align="center">30%</td><td align="center">4D</td><td align="center">5%</td><td align="center">0D</td></tr><tr><td align="center">79%</td><td align="center">C9</td><td align="center">54%</td><td align="center">8A</td><td align="center">29%</td><td align="center">4A</td><td align="center">4%</td><td align="center">0A</td></tr><tr><td align="center">78%</td><td align="center">C7</td><td align="center">53%</td><td align="center">87</td><td align="center">28%</td><td align="center">47</td><td align="center">3%</td><td align="center">08</td></tr><tr><td align="center">77%</td><td align="center">C4</td><td align="center">52%</td><td align="center">85</td><td align="center">27%</td><td align="center">45</td><td align="center">2%</td><td align="center">05</td></tr><tr><td align="center">76%</td><td align="center">C2</td><td align="center">51%</td><td align="center">82</td><td align="center">26%</td><td align="center">42</td><td align="center">1%</td><td align="center">03</td></tr><tr><td align="center"></td><td align="center"></td><td align="center"></td><td align="center"></td><td align="center"></td><td align="center"></td><td align="center">0%</td><td align="center">00</td></tr></tbody></table><p>几个常用锚点背下来能应付 80% 的场景：不透明 100% &#x3D; <code>FF</code>，半透明 50% &#x3D; <code>80</code>，全透明 0% &#x3D; <code>00</code>。</p><p>原理其实一行就讲完：<code>十六进制值 = round(不透明度 × 255)</code>。表忘在这篇文章里了？现算也来得及。</p>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/android-color-alpha/</id>
    <link href="https://www.listenergao.com/2026/07/03/android-color-alpha/"/>
    <published>2026-07-03T10:10:00.000Z</published>
    <summary>
      <![CDATA[<p>设计师：”这里用 #FFFFFF，透明度 40%。”<br>你：（打开计算器，陷入沉思）</p>
<p>这个场景每个 Android 开发者都不陌生——标注图上颜色是 RGB、透明度却是百分比，而代码里要的是 <code>#AARRGGBB</code>。这篇就是那张让你告别心算的百分比 ↔ 十六进制对照表：40% 透明度的白色，就是 <code>#99FFFFFF</code>，抄走。</p>]]>
    </summary>
    <title>Android 颜色透明度（Alpha）十六进制对照表</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="Android" scheme="https://www.listenergao.com/categories/Android/"/>
    <category term="Android" scheme="https://www.listenergao.com/tags/Android/"/>
    <content>
      <![CDATA[<p>每个 Android 开发者大概都经历过这个剧本：debug 包千好万好，release 包一打开就闪退，一查崩溃堆栈全是 <code>a.b.c.a(Unknown Source)</code>——恭喜，你被混淆背刺了。</p><p>这篇是我踩坑多年攒下的混淆配置笔记，覆盖参数设置、keep 规则语法、常用规则模板、规则叠加机制和资源压缩，最后聊聊 ProGuard 与 R8 该选谁。官方文档见 <a href="https://developer.android.com/studio/build/shrink-code?hl=zh-cn">Shrink, obfuscate, and optimize your app</a>。</p><span id="more"></span><h2 id="一、混淆参数设置"><a href="#一、混淆参数设置" class="headerlink" title="一、混淆参数设置"></a>一、混淆参数设置</h2><figure class="highlight ldif"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs ldif"><span class="hljs-literal">-</span>optimizationpasses 5                       <span class="hljs-comment"># 代码混淆的压缩比例，值介于0-7，默认5</span><br><span class="hljs-literal">-</span>verbose                                    <span class="hljs-comment"># 混淆时记录日志</span><br><span class="hljs-literal">-</span>dontoptimize                               <span class="hljs-comment"># 不优化输入的类文件</span><br><span class="hljs-literal">-</span>dontshrink                                 <span class="hljs-comment"># 关闭压缩</span><br><span class="hljs-literal">-</span>dontpreverify                              <span class="hljs-comment"># 关闭预校验(作用于Java平台，Android不需要，去掉可加快混淆)</span><br><span class="hljs-literal">-</span>dontobfuscate                              <span class="hljs-comment"># 关闭混淆</span><br><span class="hljs-literal">-</span>ignorewarnings                             <span class="hljs-comment"># 忽略警告</span><br><span class="hljs-literal">-</span>dontwarn com.squareup.okhttp.**            <span class="hljs-comment"># 指定类不输出警告信息</span><br><span class="hljs-literal">-</span>dontusemixedcaseclassnames                 <span class="hljs-comment"># 混淆后类名都为小写</span><br><span class="hljs-literal">-</span>dontskipnonpubliclibraryclasses            <span class="hljs-comment"># 不跳过非公共的库的类</span><br><span class="hljs-literal">-</span>printmapping mapping.txt                   <span class="hljs-comment"># 生成原类名与混淆后类名的映射文件mapping.txt</span><br><span class="hljs-literal">-</span>useuniqueclassmembernames                  <span class="hljs-comment"># 把混淆类中的方法名也混淆</span><br><span class="hljs-literal">-</span>allowaccessmodification                    <span class="hljs-comment"># 优化时允许访问并修改有修饰符的类及类的成员</span><br><span class="hljs-literal">-</span>renamesourcefileattribute SourceFile       <span class="hljs-comment"># 将源码中有意义的类名转换成SourceFile，用于定位混淆后的崩溃代码</span><br><span class="hljs-literal">-</span>keepattributes SourceFile,LineNumberTable  <span class="hljs-comment"># 保留行号</span><br><span class="hljs-literal">-</span>keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod <span class="hljs-comment"># 避免混淆注解、内部类、泛型、匿名类</span><br><span class="hljs-literal">-</span>optimizations !code/simplification/cast,!field/ ,!class/merging/   <span class="hljs-comment"># 指定混淆时采用的算法</span><br></code></pre></td></tr></table></figure><h2 id="二、keep-规则语法"><a href="#二、keep-规则语法" class="headerlink" title="二、keep 规则语法"></a>二、keep 规则语法</h2><p>保持规则的语法组成：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-attr">[保持命令]</span> <span class="hljs-selector-attr">[类]</span> &#123;<br>    <span class="hljs-selector-attr">[成员]</span><br>&#125;<br></code></pre></td></tr></table></figure><p><strong>保持命令：</strong></p><figure class="highlight ldif"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs ldif"><span class="hljs-literal">-</span>keep                           <span class="hljs-comment"># 防止类和类成员被移除或被混淆</span><br><span class="hljs-literal">-</span>keepnames                      <span class="hljs-comment"># 防止类和类成员被混淆</span><br><span class="hljs-literal">-</span>keepclassmembers               <span class="hljs-comment"># 防止类成员被移除或被混淆</span><br><span class="hljs-literal">-</span>keepclassmembernames           <span class="hljs-comment"># 防止类成员被混淆</span><br><span class="hljs-literal">-</span>keepclasseswithmembers         <span class="hljs-comment"># 防止拥有该成员的类和类成员被移除或被混淆</span><br><span class="hljs-literal">-</span>keepclasseswithmembernames     <span class="hljs-comment"># 防止拥有该成员的类和类成员被混淆</span><br></code></pre></td></tr></table></figure><p><strong>类的匹配：</strong></p><ul><li>访问修饰符：<code>public</code>、<code>private</code>、<code>protected</code></li><li>通配符 <code>*</code>：匹配任意长度字符，但不包含包名分隔符 <code>.</code></li><li>通配符 <code>**</code>：匹配任意长度字符，且包含包名分隔符 <code>.</code></li><li><code>extends</code>：匹配某个父类的子类</li><li><code>implements</code>：匹配实现了某接口的类</li><li><code>$</code>：内部类</li></ul><p><strong>成员的匹配：</strong></p><ul><li><code>&lt;init&gt;</code>：匹配所有构造器</li><li><code>&lt;fields&gt;</code>：匹配所有域</li><li><code>&lt;methods&gt;</code>：匹配所有方法</li><li>除了 <code>*</code> 和 <code>**</code>，还支持 <code>***</code> 通配符，匹配任意参数类型</li><li><code>...</code>：匹配任意长度的任意类型参数，如 <code>void test(...)</code> 可以匹配不同参数个数的 test 方法</li></ul><h2 id="三、常用混淆规则模板"><a href="#三、常用混淆规则模板" class="headerlink" title="三、常用混淆规则模板"></a>三、常用混淆规则模板</h2><figure class="highlight perl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><code class="hljs perl"><span class="hljs-comment"># 不混淆某个类的类名，及类中的内容</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">example</span>.<span class="hljs-title">Test</span> </span>&#123; *; &#125;<br><br><span class="hljs-comment"># 不混淆指定包名下的类名，不包括子包下的类名</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>*</span><br><span class="hljs-class"></span><br><span class="hljs-class"># 不混淆指定包名下的类名，及类里的内容</span><br><span class="hljs-class">-<span class="hljs-title">keep</span> <span class="hljs-title">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>* </span>&#123;*;&#125;<br><br><span class="hljs-comment"># 不混淆指定包名下的类名，包括子包下的类名</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>**</span><br><span class="hljs-class"></span><br><span class="hljs-class"># 不混淆某个类的子类</span><br><span class="hljs-class">-<span class="hljs-title">keep</span> <span class="hljs-title">public</span> <span class="hljs-title">class</span> * <span class="hljs-title">extends</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">base</span>.<span class="hljs-title">BaseFragment</span></span><br><span class="hljs-class"></span><br><span class="hljs-class"># 不混淆实现了某个接口的类</span><br><span class="hljs-class">-<span class="hljs-title">keep</span> <span class="hljs-title">class</span> * <span class="hljs-title">implements</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">dao</span>.<span class="hljs-title">DaoImp</span></span><br><span class="hljs-class"></span><br><span class="hljs-class"># 不混淆类名中包含了&quot;<span class="hljs-title">entity</span>&quot;的类，及类中内容</span><br><span class="hljs-class">-<span class="hljs-title">keep</span> <span class="hljs-title">class</span> **.*<span class="hljs-title">entity</span>*.** </span>&#123;*;&#125;<br><br><span class="hljs-comment"># 不混淆内部类中的所有public内容</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">widget</span>.<span class="hljs-title">CustomView</span>$<span class="hljs-title">OnClickInterface</span> </span>&#123;<br>    public *;<br>&#125;<br><br><span class="hljs-comment"># 保持类中特定内容而不是所有内容</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">example</span>.<span class="hljs-title">Test</span></span>&#123;<br>    &lt;init&gt;;     <span class="hljs-comment"># 匹配所有构造器</span><br>    &lt;fields&gt;;   <span class="hljs-comment"># 匹配所有域</span><br>    &lt;methods&gt;;  <span class="hljs-comment"># 匹配所有方法</span><br>&#125;<br><br><span class="hljs-comment"># 可以在&lt;fields&gt;或&lt;methods&gt;前面加上 private/public/native 等进一步限定</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">example</span>.<span class="hljs-title">Test</span></span>&#123;<br>    public &lt;methods&gt;;                   <span class="hljs-comment"># 该类下所有公有方法不被混淆</span><br>    private &lt;methods&gt;;                  <span class="hljs-comment"># 该类下所有私有方法不被混淆</span><br>    public &lt;init&gt;(java.lang.String);    <span class="hljs-comment"># 该类的 String 参数构造方法不被混淆</span><br>&#125;<br><br><span class="hljs-comment"># 保留内部类需要用 $ 符号：保持 Test 类中的 MyClass 不被混淆</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">cn</span>.<span class="hljs-title">listenergao</span>.<span class="hljs-title">myapp</span>.<span class="hljs-title">example</span>.<span class="hljs-title">Test</span>$<span class="hljs-title">MyClass</span></span>&#123;*;&#125;<br><br><span class="hljs-comment"># 不混淆 native 方法（JNI 依赖完整的包名类名方法名）</span><br>-keepclasseswithmembernames <span class="hljs-class"><span class="hljs-keyword">class</span> * </span>&#123;<br>    native &lt;methods&gt;;<br>&#125;<br><br><span class="hljs-comment"># 不混淆枚举类（values/valueOf 会被反射调用）</span><br>-keepclassmembers enum * &#123;<br>  public static **[] <span class="hljs-keyword">values</span>();<br>  public static ** valueOf(java.lang.String);<br>&#125;<br><br><span class="hljs-comment"># 不混淆资源类</span><br>-keepclassmembers <span class="hljs-class"><span class="hljs-keyword">class</span> **.<span class="hljs-title">R</span>$* </span>&#123;<br>    public static &lt;fields&gt;;<br>&#125;<br><br><span class="hljs-comment"># 不混淆实现了 Serializable 接口的类成员</span><br>-keepclassmembers <span class="hljs-class"><span class="hljs-keyword">class</span> * <span class="hljs-title">implements</span> <span class="hljs-title">java</span>.<span class="hljs-title">io</span>.<span class="hljs-title">Serializable</span> </span>&#123;<br>    static final long serialVersionUID;<br>    private static final java.io.ObjectStreamField[] serialPersistentFields;<br>    private void writeObject(java.io.ObjectOutputStream);<br>    private void readObject(java.io.ObjectInputStream);<br>    java.lang.Object writeReplace();<br>    java.lang.Object readResolve();<br>&#125;<br><br><span class="hljs-comment"># 不混淆实现了 Parcelable 接口的类成员</span><br>-keep <span class="hljs-class"><span class="hljs-keyword">class</span> * <span class="hljs-title">implements</span> <span class="hljs-title">android</span>.<span class="hljs-title">os</span>.<span class="hljs-title">Parcelable</span> </span>&#123;<br>    public static final android.os.Parcelable<span class="hljs-variable">$Creator</span> *;<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>注意事项（每一条背后都是一次线上事故，建议裱起来）：</strong></p><ol><li>JNI 方法不可混淆，方法名需与 native 方法保持一致</li><li>反射用到的类不混淆，否则反射可能出问题</li><li>四大组件、Application 子类、Framework 层下的类、自定义 View 默认不会被混淆，无需另外配置</li><li>WebView 的 JS 调用接口方法不可混淆</li><li>注解相关的类不混淆</li><li>GSON、Fastjson 等解析的 Bean 数据类不可混淆</li><li>枚举类中的 values 和 valueOf 这两个方法不可混淆（反射调用）</li><li>继承 Parcelable 和 Serializable 等可序列化的类不可混淆</li><li>第三方库或 SDK 参考第三方提供的混淆规则，没提供的话建议第三方包全部不混淆</li></ol><h2 id="四、混淆规则的叠加"><a href="#四、混淆规则的叠加" class="headerlink" title="四、混淆规则的叠加"></a>四、混淆规则的叠加</h2><p>你有没有想过一个灵异现象：主模块的 proguard-rules.pro 明明空空如也，代码却被混淆了？这不是闹鬼，是因为混淆规则是<strong>叠加</strong>的，来源远不止你写的那一份：</p><ol><li><strong>各模块的 proguard-rules.pro</strong> —— 子模块也可以有，某个模块的配置可能影响其它模块</li><li><strong>proguard-android-optimize.txt</strong> —— AGP 编译时生成，包含对大多数 Android 项目有用的规则，并启用 <code>@Keep*</code> 注解；AGP 还提供 proguard-defaults.txt 和 proguard-android.txt，可通过 <code>getDefaultProguardFile</code> 设置，建议用 optimize 这份（多了优化配置）</li><li><strong>build&#x2F;intermediates&#x2F;proguard-rules&#x2F;debug&#x2F;aapt_rules.txt</strong> —— AAPT2 根据清单文件、布局及其他资源的引用自动生成保留规则，比如不混淆每个 Activity</li><li><strong>AAR 库</strong>的 <code>/proguard.txt</code></li><li><strong>Jar 库</strong>的 <code>/META-INF/proguard/</code></li></ol><p>想查看所有规则叠加后的最终混淆规则，在主模块 proguard-rules.pro 添加：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">-printconfiguration .<span class="hljs-regexp">/build/</span>outputs<span class="hljs-regexp">/mapping/</span>full-config.txt<br></code></pre></td></tr></table></figure><h2 id="五、资源压缩"><a href="#五、资源压缩" class="headerlink" title="五、资源压缩"></a>五、资源压缩</h2><p>资源压缩分两步：<strong>资源合并</strong>与<strong>资源移除</strong>。</p><p><strong>资源合并</strong>：无论是否配置 <code>shrinkResources true</code>，AGP 构建 APK 时都会执行。存在两个或更多同名资源时，AGP 从重复项中选择优先级更高的文件传递给 AAPT2。级联优先顺序：</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">依赖项 → 主资源 → 渠道 → 构建类型<br></code></pre></td></tr></table></figure><p>比如重复资源存在于主资源及渠道中，Gradle 会选渠道中的资源；但如果重复资源在同一层次（如 src&#x2F;main&#x2F;res&#x2F; 和 src&#x2F;main&#x2F;res2&#x2F;），Gradle 会报资源合并错误。</p><p><strong>资源移除</strong>：开启资源压缩后，所有未被使用的资源默认会被移除。想自定义保留&#x2F;移除，可在 <code>res/raw/</code> 下创建 keep.xml（此文件不会打包进 APK，支持通配符 <code>*</code>）：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">&quot;1.0&quot;</span> encoding=<span class="hljs-string">&quot;utf-8&quot;</span>?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">resources</span> <span class="hljs-attr">xmlns:tools</span>=<span class="hljs-string">&quot;http://schemas.android.com/tools&quot;</span></span><br><span class="hljs-tag">    <span class="hljs-attr">tools:keep</span>=<span class="hljs-string">&quot;@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*&quot;</span></span><br><span class="hljs-tag">    <span class="hljs-attr">tools:discard</span>=<span class="hljs-string">&quot;@layout/unused2&quot;</span></span><br><span class="hljs-tag">    <span class="hljs-attr">tools:shrinkMode</span>=<span class="hljs-string">&quot;strict&quot;</span>/&gt;</span><br></code></pre></td></tr></table></figure><p><code>shrinkMode</code> 可选 strict &#x2F; safe：前者严格按 keep 和 discard 指定的资源保留；后者保守删除未引用资源（如代码中用 <code>Resources.getIdentifier()</code> 引用的资源会保留）。</p><p>另外还可以用 resConfigs 移除不需要的备用资源，比如只保留中文：</p><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs groovy">android &#123;<br>    defaultConfig &#123;<br>        resConfigs <span class="hljs-string">&quot;zh-rCN&quot;</span> <span class="hljs-comment">// 不需要国际化时只打包中文资源</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="六、ProGuard-与-R8"><a href="#六、ProGuard-与-R8" class="headerlink" title="六、ProGuard 与 R8"></a>六、ProGuard 与 R8</h2><ul><li><strong>ProGuard</strong>：压缩、优化和混淆 Java 字节码的免费工具，<a href="https://github.com/Guardsquare/proguard">开源仓库</a></li><li><strong>R8</strong>：ProGuard 的替代工具，兼容现有 ProGuard 规则，更快更强。AGP 3.4.0 及以上默认使用 R8</li></ul><p>结论：直接用 R8，别纠结。兼容绝大部分 ProGuard 规则、编译更快、对 Kotlin 更友好——想换回 ProGuard 属于「可以但没必要」系列。</p><p>构建后会在 <code>build/outputs/mapping/release/</code> 输出以下文件：</p><ul><li><strong>mapping.txt</strong>：原始与混淆后的类、方法、字段名称映射。崩溃堆栈还原全靠它，发版后务必留存——弄丢 mapping 文件再看线上崩溃，就像拿着一张全是马赛克的藏宝图</li><li><strong>seeds.txt</strong>：未进行混淆的类与成员</li><li><strong>usage.txt</strong>：APK 中被移除的代码</li><li><strong>resources.txt</strong>：资源优化记录</li></ul><p>这些文件不一定都有，可以在 proguard-rules.pro 显式指定输出：</p><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs n1ql">-printmapping ./<span class="hljs-keyword">build</span>/outputs/<span class="hljs-keyword">mapping</span>/<span class="hljs-keyword">mapping</span>.txt<br>-printseeds ./<span class="hljs-keyword">build</span>/outputs/<span class="hljs-keyword">mapping</span>/seeds.txt<br>-printusage ./<span class="hljs-keyword">build</span>/outputs/<span class="hljs-keyword">mapping</span>/usage.txt<br></code></pre></td></tr></table></figure>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/android-proguard-r8/</id>
    <link href="https://www.listenergao.com/2026/07/03/android-proguard-r8/"/>
    <published>2026-07-03T10:00:00.000Z</published>
    <summary>
      <![CDATA[<p>每个 Android 开发者大概都经历过这个剧本：debug 包千好万好，release 包一打开就闪退，一查崩溃堆栈全是 <code>a.b.c.a(Unknown Source)</code>——恭喜，你被混淆背刺了。</p>
<p>这篇是我踩坑多年攒下的混淆配置笔记，覆盖参数设置、keep 规则语法、常用规则模板、规则叠加机制和资源压缩，最后聊聊 ProGuard 与 R8 该选谁。官方文档见 <a href="https://developer.android.com/studio/build/shrink-code?hl=zh-cn">Shrink, obfuscate, and optimize your app</a>。</p>]]>
    </summary>
    <title>Android 混淆实践笔记：ProGuard 与 R8</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
  <entry>
    <author>
      <name>ListenerGao</name>
    </author>
    <category term="博客" scheme="https://www.listenergao.com/tags/%E5%8D%9A%E5%AE%A2/"/>
    <content>
      <![CDATA[<p>博客重新搭建完成：Hexo + Fluid 主题，源码托管在 GitHub main 分支，GitHub Actions 自动构建并发布到 GitHub Pages。</p><p>这次源码就是仓库本身，不会再丢了。</p><span id="more"></span><h2 id="日常写作流程"><a href="#日常写作流程" class="headerlink" title="日常写作流程"></a>日常写作流程</h2><p>整个流程只有三步：写、看、推。</p><h3 id="1-新建文章"><a href="#1-新建文章" class="headerlink" title="1. 新建文章"></a>1. 新建文章</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npx hexo new <span class="hljs-string">&quot;文章标题&quot;</span><br></code></pre></td></tr></table></figure><p>会在 <code>source/_posts/</code> 下生成对应的 Markdown 文件，头部自带 front-matter：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-meta">---</span><br><span class="hljs-attr">title:</span> <span class="hljs-string">文章标题</span><br><span class="hljs-attr">date:</span> <span class="hljs-number">2026-07-03 16:16:15</span><br><span class="hljs-attr">tags:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-string">标签名</span><br><span class="hljs-meta">---</span><br></code></pre></td></tr></table></figure><p>正文直接写 Markdown。想控制首页摘要截断位置，在正文中插入 <code>&lt;!-- more --&gt;</code> 即可。</p><h3 id="2-本地预览"><a href="#2-本地预览" class="headerlink" title="2. 本地预览"></a>2. 本地预览</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npx hexo server<br></code></pre></td></tr></table></figure><p>浏览器打开 <a href="http://localhost:4000/">http://localhost:4000</a> 实时预览，文章内容保存后自动刷新（改配置文件需要重启）。</p><h3 id="3-发布"><a href="#3-发布" class="headerlink" title="3. 发布"></a>3. 发布</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">git add .<br>git commit -m <span class="hljs-string">&quot;post: 文章标题&quot;</span><br>git push<br></code></pre></td></tr></table></figure><p>push 到 main 分支后，GitHub Actions 会自动构建并部署，一两分钟后文章就出现在线上了。构建状态可以在仓库的 Actions 页面查看。</p><h2 id="常用命令速查"><a href="#常用命令速查" class="headerlink" title="常用命令速查"></a>常用命令速查</h2><table><thead><tr><th>命令</th><th>作用</th></tr></thead><tbody><tr><td><code>npx hexo new &quot;标题&quot;</code></td><td>新建文章</td></tr><tr><td><code>npx hexo new page 页面名</code></td><td>新建独立页面（如关于页）</td></tr><tr><td><code>npx hexo server</code></td><td>本地预览</td></tr><tr><td><code>npx hexo generate</code></td><td>手动构建（验证有没有报错）</td></tr><tr><td><code>npx hexo clean</code></td><td>清缓存，构建结果异常时先跑这个</td></tr></tbody></table><h2 id="配置文件说明"><a href="#配置文件说明" class="headerlink" title="配置文件说明"></a>配置文件说明</h2><ul><li><code>_config.yml</code>：Hexo 站点配置（站点标题、语言、URL 等）</li><li><code>_config.fluid.yml</code>：Fluid 主题配置（导航栏、头像、评论、统计等），只写需要覆盖的项</li><li>换电脑后只需 <code>git clone</code> + <code>npm install</code>，环境就恢复了——这正是源码进仓库的意义。</li></ul>]]>
    </content>
    <id>https://www.listenergao.com/2026/07/03/Hello-Hexo/</id>
    <link href="https://www.listenergao.com/2026/07/03/Hello-Hexo/"/>
    <published>2026-07-03T08:16:15.000Z</published>
    <summary>
      <![CDATA[<p>博客重新搭建完成：Hexo + Fluid 主题，源码托管在 GitHub main 分支，GitHub Actions 自动构建并发布到 GitHub Pages。</p>
<p>这次源码就是仓库本身，不会再丢了。</p>]]>
    </summary>
    <title>Hello Hexo</title>
    <updated>2026-07-16T08:50:48.291Z</updated>
  </entry>
</feed>
