@gkd-kit/docs 0.0.1773041526257 → 0.0.1775561895429

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.vitepress/dist/404.html +8 -8
  2. package/.vitepress/dist/404_.md +8 -8
  3. package/.vitepress/dist/_config.json +3 -1
  4. package/.vitepress/dist/api/index.html +12 -12
  5. package/.vitepress/dist/api/index_.md +12 -12
  6. package/.vitepress/dist/api/interfaces/RawApp.html +12 -12
  7. package/.vitepress/dist/api/interfaces/RawAppGroup.html +12 -12
  8. package/.vitepress/dist/api/interfaces/RawAppGroup_.md +12 -12
  9. package/.vitepress/dist/api/interfaces/RawAppRule.html +16 -15
  10. package/.vitepress/dist/api/interfaces/RawAppRuleProps.html +12 -12
  11. package/.vitepress/dist/api/interfaces/RawAppRuleProps_.md +12 -12
  12. package/.vitepress/dist/api/interfaces/RawAppRule_.md +16 -15
  13. package/.vitepress/dist/api/interfaces/RawApp_.md +12 -12
  14. package/.vitepress/dist/api/interfaces/RawCategory.html +12 -12
  15. package/.vitepress/dist/api/interfaces/RawCategory_.md +12 -12
  16. package/.vitepress/dist/api/interfaces/RawCommonProps.html +12 -12
  17. package/.vitepress/dist/api/interfaces/RawCommonProps_.md +12 -12
  18. package/.vitepress/dist/api/interfaces/RawGlobalApp.html +12 -12
  19. package/.vitepress/dist/api/interfaces/RawGlobalApp_.md +12 -12
  20. package/.vitepress/dist/api/interfaces/RawGlobalGroup.html +12 -12
  21. package/.vitepress/dist/api/interfaces/RawGlobalGroup_.md +12 -12
  22. package/.vitepress/dist/api/interfaces/RawGlobalRule.html +16 -15
  23. package/.vitepress/dist/api/interfaces/RawGlobalRuleProps.html +12 -12
  24. package/.vitepress/dist/api/interfaces/RawGlobalRuleProps_.md +12 -12
  25. package/.vitepress/dist/api/interfaces/RawGlobalRule_.md +16 -15
  26. package/.vitepress/dist/api/interfaces/RawGroupProps.html +12 -12
  27. package/.vitepress/dist/api/interfaces/RawGroupProps_.md +12 -12
  28. package/.vitepress/dist/api/interfaces/RawRuleProps.html +16 -15
  29. package/.vitepress/dist/api/interfaces/RawRuleProps_.md +16 -15
  30. package/.vitepress/dist/api/interfaces/RawSubscription.html +12 -12
  31. package/.vitepress/dist/api/interfaces/RawSubscription_.md +12 -12
  32. package/.vitepress/dist/api/type-aliases/IArray.html +12 -12
  33. package/.vitepress/dist/api/type-aliases/IArray_.md +12 -12
  34. package/.vitepress/dist/api/type-aliases/Integer.html +12 -12
  35. package/.vitepress/dist/api/type-aliases/IntegerMatcher.html +12 -12
  36. package/.vitepress/dist/api/type-aliases/IntegerMatcher_.md +12 -12
  37. package/.vitepress/dist/api/type-aliases/Integer_.md +12 -12
  38. package/.vitepress/dist/api/type-aliases/Position.html +17 -14
  39. package/.vitepress/dist/api/type-aliases/Position_.md +17 -14
  40. package/.vitepress/dist/api/type-aliases/StringMatcher.html +12 -12
  41. package/.vitepress/dist/api/type-aliases/StringMatcher_.md +12 -12
  42. package/.vitepress/dist/api/type-aliases/SwipeArg.html +26 -0
  43. package/.vitepress/dist/api/type-aliases/SwipeArg_.md +26 -0
  44. package/.vitepress/dist/assets/{api_index.md.Uspfy_7_.js → api_index.md.DbsdFYfN.js} +1 -1
  45. package/.vitepress/dist/assets/{api_index.md.Uspfy_7_.lean.js → api_index.md.DbsdFYfN.lean.js} +1 -1
  46. package/.vitepress/dist/assets/{api_interfaces_RawAppRule.md.C4S0uX3V.js → api_interfaces_RawAppRule.md.8M9z50Zw.js} +1 -1
  47. package/.vitepress/dist/assets/{api_interfaces_RawAppRule.md.C4S0uX3V.lean.js → api_interfaces_RawAppRule.md.8M9z50Zw.lean.js} +1 -1
  48. package/.vitepress/dist/assets/{api_interfaces_RawGlobalRule.md.CJIztWM_.js → api_interfaces_RawGlobalRule.md.DoipTbY2.js} +1 -1
  49. package/.vitepress/dist/assets/{api_interfaces_RawGlobalRule.md.CJIztWM_.lean.js → api_interfaces_RawGlobalRule.md.DoipTbY2.lean.js} +1 -1
  50. package/.vitepress/dist/assets/api_interfaces_RawRuleProps.md.DAyRdUkK.js +1 -0
  51. package/.vitepress/dist/assets/api_interfaces_RawRuleProps.md.DAyRdUkK.lean.js +1 -0
  52. package/.vitepress/dist/assets/{api_type-aliases_Position.md.Ca9iQqw9.js → api_type-aliases_Position.md.ynqsGzVM.js} +6 -3
  53. package/.vitepress/dist/assets/api_type-aliases_Position.md.ynqsGzVM.lean.js +1 -0
  54. package/.vitepress/dist/assets/api_type-aliases_SwipeArg.md.BBrbAV2_.js +1 -0
  55. package/.vitepress/dist/assets/api_type-aliases_SwipeArg.md.BBrbAV2_.lean.js +1 -0
  56. package/.vitepress/dist/assets/{app.DVhfhT9I.js → app.Bn70pxTo.js} +1 -1
  57. package/.vitepress/dist/assets/chunks/@localSearchIndexroot.Cu11wy8j.js +1 -0
  58. package/.vitepress/dist/assets/chunks/{VPLocalSearchBox.BX79nG7w.js → VPLocalSearchBox.CjAJ_IDV.js} +2 -2
  59. package/.vitepress/dist/assets/chunks/{theme.B8xL5v-l.js → theme.BJPIb0kN.js} +1 -1
  60. package/.vitepress/dist/assets/{guide_example.md.Bdszvy8q.js → guide_example.md.D9ErCjbg.js} +1 -1
  61. package/.vitepress/dist/assets/{guide_example.md.Bdszvy8q.lean.js → guide_example.md.D9ErCjbg.lean.js} +1 -1
  62. package/.vitepress/dist/assets/{guide_external.md.B7gVfQ0Z.js → guide_external.md.CPuP1yVI.js} +1 -1
  63. package/.vitepress/dist/assets/{guide_external.md.B7gVfQ0Z.lean.js → guide_external.md.CPuP1yVI.lean.js} +1 -1
  64. package/.vitepress/dist/assets/{guide_faq.md.f0uQS5Xi.js → guide_faq.md.C3S8KsGE.js} +1 -1
  65. package/.vitepress/dist/assets/{guide_faq.md.f0uQS5Xi.lean.js → guide_faq.md.C3S8KsGE.lean.js} +1 -1
  66. package/.vitepress/dist/assets/{guide_index.md.CBWr4PoQ.js → guide_index.md.CHq6OmLn.js} +1 -1
  67. package/.vitepress/dist/assets/{guide_index.md.CBWr4PoQ.lean.js → guide_index.md.CHq6OmLn.lean.js} +1 -1
  68. package/.vitepress/dist/assets/{guide_node.md.3F28p5GJ.js → guide_node.md.j2HRdLQ6.js} +1 -1
  69. package/.vitepress/dist/assets/{guide_node.md.3F28p5GJ.lean.js → guide_node.md.j2HRdLQ6.lean.js} +1 -1
  70. package/.vitepress/dist/assets/{guide_optimize.md.4jOEICqw.js → guide_optimize.md.CsiXtPKC.js} +1 -1
  71. package/.vitepress/dist/assets/{guide_optimize.md.4jOEICqw.lean.js → guide_optimize.md.CsiXtPKC.lean.js} +1 -1
  72. package/.vitepress/dist/assets/{guide_privacy.md.DimI8XRq.js → guide_privacy.md.C10kF9f9.js} +1 -1
  73. package/.vitepress/dist/assets/{guide_privacy.md.DimI8XRq.lean.js → guide_privacy.md.C10kF9f9.lean.js} +1 -1
  74. package/.vitepress/dist/assets/{guide_selector.md.BMLnKvvL.js → guide_selector.md.DcUL3KMV.js} +1 -1
  75. package/.vitepress/dist/assets/{guide_selector.md.BMLnKvvL.lean.js → guide_selector.md.DcUL3KMV.lean.js} +1 -1
  76. package/.vitepress/dist/assets/{guide_snapshot.md.C2HrRBx5.js → guide_snapshot.md.DuGsyVR-.js} +1 -1
  77. package/.vitepress/dist/assets/{guide_snapshot.md.C2HrRBx5.lean.js → guide_snapshot.md.DuGsyVR-.lean.js} +1 -1
  78. package/.vitepress/dist/assets/{guide_sponsor.md.BVkQDkKi.js → guide_sponsor.md.Cn8i_w2B.js} +1 -1
  79. package/.vitepress/dist/assets/{guide_sponsor.md.BVkQDkKi.lean.js → guide_sponsor.md.Cn8i_w2B.lean.js} +1 -1
  80. package/.vitepress/dist/assets/{guide_subscription.md.DmtYneCb.js → guide_subscription.md.DdMkXeKz.js} +1 -1
  81. package/.vitepress/dist/assets/{guide_subscription.md.DmtYneCb.lean.js → guide_subscription.md.DdMkXeKz.lean.js} +1 -1
  82. package/.vitepress/dist/assets/{guide_terms.md.Di3btgy4.js → guide_terms.md.NplGigUN.js} +1 -1
  83. package/.vitepress/dist/assets/{guide_terms.md.Di3btgy4.lean.js → guide_terms.md.NplGigUN.lean.js} +1 -1
  84. package/.vitepress/dist/assets/{guide_what-is-gkd.md.CJzJNXDR.js → guide_what-is-gkd.md.joPKvKOr.js} +1 -1
  85. package/.vitepress/dist/assets/{guide_what-is-gkd.md.CJzJNXDR.lean.js → guide_what-is-gkd.md.joPKvKOr.lean.js} +1 -1
  86. package/.vitepress/dist/assets/{index.md.BSPbp2yq.js → index.md.B7teHTeR.js} +1 -1
  87. package/.vitepress/dist/assets/{index.md.BSPbp2yq.lean.js → index.md.B7teHTeR.lean.js} +1 -1
  88. package/.vitepress/dist/assets/style.DmRq6upP.css +1 -1
  89. package/.vitepress/dist/guide/example.html +12 -12
  90. package/.vitepress/dist/guide/example_.md +12 -12
  91. package/.vitepress/dist/guide/external.html +12 -12
  92. package/.vitepress/dist/guide/external_.md +12 -12
  93. package/.vitepress/dist/guide/faq.html +12 -12
  94. package/.vitepress/dist/guide/faq_.md +12 -12
  95. package/.vitepress/dist/guide/index.html +12 -12
  96. package/.vitepress/dist/guide/index_.md +12 -12
  97. package/.vitepress/dist/guide/node.html +12 -12
  98. package/.vitepress/dist/guide/node_.md +12 -12
  99. package/.vitepress/dist/guide/optimize.html +12 -12
  100. package/.vitepress/dist/guide/optimize_.md +12 -12
  101. package/.vitepress/dist/guide/privacy.html +12 -12
  102. package/.vitepress/dist/guide/privacy_.md +12 -12
  103. package/.vitepress/dist/guide/selector.html +12 -12
  104. package/.vitepress/dist/guide/selector_.md +12 -12
  105. package/.vitepress/dist/guide/snapshot.html +12 -12
  106. package/.vitepress/dist/guide/snapshot_.md +12 -12
  107. package/.vitepress/dist/guide/sponsor.html +12 -12
  108. package/.vitepress/dist/guide/sponsor_.md +12 -12
  109. package/.vitepress/dist/guide/subscription.html +12 -12
  110. package/.vitepress/dist/guide/subscription_.md +12 -12
  111. package/.vitepress/dist/guide/terms.html +12 -12
  112. package/.vitepress/dist/guide/terms_.md +12 -12
  113. package/.vitepress/dist/guide/what-is-gkd.html +12 -12
  114. package/.vitepress/dist/guide/what-is-gkd_.md +12 -12
  115. package/.vitepress/dist/hashmap.json +1 -1
  116. package/.vitepress/dist/index.html +12 -12
  117. package/.vitepress/dist/index_.md +12 -12
  118. package/_config.json +3 -1
  119. package/package.json +5 -1
  120. package/.vitepress/dist/assets/api_interfaces_RawRuleProps.md.B0cLuJvt.js +0 -1
  121. package/.vitepress/dist/assets/api_interfaces_RawRuleProps.md.B0cLuJvt.lean.js +0 -1
  122. package/.vitepress/dist/assets/api_type-aliases_Position.md.Ca9iQqw9.lean.js +0 -1
  123. package/.vitepress/dist/assets/chunks/@localSearchIndexroot.BSpXxL8b.js +0 -1
@@ -1,4 +1,4 @@
1
- import{_ as o,I as r,c as d,o as c,aq as i,J as l,j as e,a as n,w as u}from"./chunks/framework.C9O3MI31.js";const x=JSON.parse('{"title":"常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/faq.md","filePath":"guide/faq.md","lastUpdated":1773041507000}'),g={name:"guide/faq.md"};function m(h,a,k,b,P,f){const s=r("GImg"),t=r("ImageTable"),p=r("NImageGroup");return c(),d("div",null,[a[4]||(a[4]=i('<h1 id="title" tabindex="-1">常见问题 <a class="header-anchor" href="#title" aria-label="Permalink to “常见问题”">​</a></h1><p>一些可能影响使用体验的问题和对应解决方案, 某些方案可能并不适用您的机型系统</p><p>如您有更好的方案或想对现有方案进行补充, 请点击底部 <code>为此页提供修改建议</code></p><h2 id="play-diff" tabindex="-1">渠道区别 <a class="header-anchor" href="#play-diff" aria-label="Permalink to “渠道区别”">​</a></h2><p>目前有两个渠道在使用,它们可互相安装覆盖,但存在区别</p><table tabindex="0"><thead><tr><th style="text-align:center;">渠道</th><th style="text-align:center;">下载方式</th><th style="text-align:center;">自更新逻辑</th><th style="text-align:center;"><a href="#restriction">受限制的设置</a></th><th style="text-align:center;">无障碍工具声明</th></tr></thead><tbody><tr><td style="text-align:center;">gkd</td><td style="text-align:center;"><a href="/guide/">官网/GitHub</a></td><td style="text-align:center;">弹窗更新(镜像加速)</td><td style="text-align:center;">可能受限</td><td style="text-align:center;">有</td></tr><tr><td style="text-align:center;">play</td><td style="text-align:center;"><a href="https://play.google.com/store/apps/details?id=li.songe.gkd" target="_blank" rel="noreferrer">Google Play</a></td><td style="text-align:center;">无(必须Google Play)</td><td style="text-align:center;">不会</td><td style="text-align:center;">无</td></tr></tbody></table><p>根据 <a href="https://support.google.com/googleplay/android-developer/answer/10964491?hl=zh-Hans" target="_blank" rel="noreferrer">Google Play 政策</a>,必须以 <strong>支持残障人士为主要用途</strong> 才能使用 <strong>无障碍工具声明</strong></p><p>如果没有这个声明,系统会隔段时间显示通知(<a href="https://github.com/orgs/gkd-kit/discussions/744" target="_blank" rel="noreferrer">discussions#744</a>),内容如下</p><p><code>查看权限设置(GKD可以查看和控制您的屏幕。点按即可查看。)</code></p><p>如果你无法忍受这个通知,切换到 gkd 渠道即可</p><h2 id="power" tabindex="-1">耗电说明 <a class="header-anchor" href="#power" aria-label="Permalink to “耗电说明”">​</a></h2><p>首先 GKD 默认情况下并不耗电,有的人以为关闭更新检测,关闭日志就能减少耗电,并不正确</p><p>真正的耗电在于 启用的规则 和 当前应用界面无障碍节点数量及无障碍事件刷新频率</p><p>如果想追求低耗电,那应该开启少量的规则,由于之前的默认规则数量有 1300+,很多人喜欢无脑开启规则</p><p>甚至有的用户同时开启多个订阅, 而这些订阅基本都 fork 自默认订阅, 这相当于同时开启多个重复规则</p><p>开启这么多规则,并且在这些规则匹配的界面使用手机,不耗电是不可能的</p><p>此外,某些软件如抖音的无障碍节点数量比较多,并且产生无障碍事件频率也比较高</p><p>长时间下使用此类软件的规则会比较耗电,请自行考虑后再启用</p><h2 id="shizuku" tabindex="-1">shizuku <a class="header-anchor" href="#shizuku" aria-label="Permalink to “shizuku”">​</a></h2><p>shizuku 是一个能让普通应用通过 ADB 或 Root 权限直接调用 Android 系统 API 的框架</p><p>简而言之, 授权 shizuku 后 GKD 可以调用更多系统 API 获取更多状态,启用更多优化</p><p>官方原版 <a href="https://github.com/RikkaApps/Shizuku" target="_blank" rel="noreferrer">RikkaApps/Shizuku</a> 已很久未有维护记录,issue/pr 也被垃圾机器人淹没</p><p>建议使用另一位开发者的分支项目 <a href="https://github.com/thedjchi/Shizuku" target="_blank" rel="noreferrer">thedjchi/Shizuku</a>,或<a href="https://github.com/thedjchi/Shizuku/releases/latest" target="_blank" rel="noreferrer">点击前往下载</a></p><h3 id="exact-activity" tabindex="-1">界面识别 <a class="header-anchor" href="#exact-activity" aria-label="Permalink to “界面识别”">​</a></h3><p>单纯靠无障碍提供的 API 无法准确判断当前处于应用的哪个子界面 (activityId)</p><p>在此种情况下, GKD 将运行当前应用的所有规则, 容易造成无效匹配和误触</p><p>授权 shizuku 后可以让 GKD 准确识别当前应用子界面</p><h3 id="forced-tap" tabindex="-1">强制点击 <a class="header-anchor" href="#forced-tap" aria-label="Permalink to “强制点击”">​</a></h3><p>使用无障碍 API 发出的点击事件 <code>clickCenter</code> 会被某些应用识别到, 导致点击表现无效</p><p>授权 shizuku 后可以让 GKD 发出的点击事件无法被应用识别到, 从而正常触发点击</p><h3 id="work-profile" tabindex="-1">工作空间 <a class="header-anchor" href="#work-profile" aria-label="Permalink to “工作空间”">​</a></h3><p>某些用户可能选择将应用安装到其他用户空间隔离</p><p>这导致 GKD 无法从当前应用列表识别到应用已安装</p><p>授权 shizuku 后可以让 GKD 识别到其他用户空间的应用</p><ul><li>只识别主空间未安装应用</li><li>只在主空间有应用变更行为时才全量更新用户空间应用列表</li></ul><p>如果不开启此项, 对于未安装的应用, 有以下影响</p><ul><li>全局规则 的内部配置禁用失效</li><li>应用规则 不会启用</li></ul><p>对于 <code>全局规则</code> 可使用手动编辑禁用, 添加 appId 到禁用列表后将生效</p><p>若要开启 <code>应用规则</code>, 在对应订阅-应用规则-显示未安装应用-打开右侧开关即可</p><details class="details custom-block"><summary>不生效原因</summary><p>这是因为某些订阅有将近 2k 个应用, 而一般用户最多使用到 200 个</p><p>如果将 未安装的应用 的应用规则也全部开启, 这将额外占用 1800 个应用的无效规则配置内存</p></details><h2 id="persistent" tabindex="-1">后台运行 <a class="header-anchor" href="#persistent" aria-label="Permalink to “后台运行”">​</a></h2><p>如何尽量保持后台运行不被系统暂停/杀死</p><ul><li>任务切换界面给 GKD 应用卡片加锁即可</li></ul><p>一般情况下, 使用此项即可正常后台运行, 如果不行请使用下面的步骤</p><ul><li>打开 GKD 首页, 开启 <code>常驻通知</code></li><li>允许后台活动, 关闭省电策略, 或者设置 GKD 的省电策略为无限制</li><li>允许 GKD 自启动</li></ul><p>某些系统如 MagicOS9 需要打开 <code>允许后台活动</code>, 否则 GKD 在后台时会被系统暂停执行</p>',46)),l(s,{src:"0038.jpg"}),a[5]||(a[5]=e("h2",{id:"restriction",tabindex:"-1"},[n("受限制的设置 "),e("a",{class:"header-anchor",href:"#restriction","aria-label":"Permalink to “受限制的设置”"},"​")],-1)),a[6]||(a[6]=e("p",null,"无障碍列表界面提示",-1)),a[7]||(a[7]=e("blockquote",null,[e("p",null,"受限制的设置(出于安全考虑,此设置目前不可用)")],-1)),a[8]||(a[8]=e("p",null,"或提示",-1)),a[9]||(a[9]=e("blockquote",null,[e("p",null,"系统已拒绝向此应用授予访问权限")],-1)),l(t,{images:[["0014.png","0039.jpg"]]}),a[10]||(a[10]=e("p",null,"这是因为某些系统对于 不在应用商店等可信任来源安装的 不能直接开启无障碍权限",-1)),a[11]||(a[11]=e("p",null,"解除步骤: GKD 应用信息 - 允许受限制的设置, 注意某些设备位置不太一样",-1)),e("table",null,[a[0]||(a[0]=e("thead",null,[e("tr",null,[e("th",{class:"text-center!"},[n("原生系统 "),e("br"),n(" 应用信息 - 右上角 - 允许受限制的设置")]),e("th",{class:"text-center!"},[n("小米系统 "),e("br"),n(" 应用信息 - 高级设置 - 允许受限制的设置")])])],-1)),e("tbody",null,[l(p,null,{default:u(()=>[e("tr",null,[e("td",null,[l(s,{src:"0016.png"})]),e("td",null,[l(s,{src:"0040.jpg"})])])]),_:1})])]),a[12]||(a[12]=i('<p>如果按步骤开启后 无障碍列表 仍然提示不可用, 可尝试 <strong>重启设备</strong></p><p>如果应用信息右上角没有 <code>允许受限制的设置</code> 选项, 请参考下一节方案</p><h2 id="unable_open_a11y" tabindex="-1">无法开启无障碍 <a class="header-anchor" href="#unable_open_a11y" aria-label="Permalink to “无法开启无障碍”">​</a></h2><p>某些系统如 ColorOS 有更严格的无障碍限制</p><p>如果你是其他来源安装或 GKD 内部更新后也会无法开启无障碍, 表现以下行为</p><ul><li>提示 受限制的设置, 但是没有找到 允许受限制的设置 的选项</li><li>不提示 受限制的设置, 无障碍开启按钮可点击, 但点击后没有响应, 无法开启</li></ul><p>可以通过以下方式解决, 可在 设置 - 关于 - 分享应用 获取 APK 文件</p>',7)),e("ul",null,[a[2]||(a[2]=e("li",null,[e("p",null,"使用系统信任的方式进行安装, 例如在系统文件管理中查看 APK 文件后点击安装, 是覆盖安装无需卸载")],-1)),a[3]||(a[3]=e("li",null,[e("p",null,[n("如果使用系统安装器, 但是在冻结了应用安装器 "),e("code",null,"com.oplus.appdetail"),n(" 状态下安装的 APK, 需解冻后重新安装")])],-1)),e("li",null,[a[1]||(a[1]=e("p",null,[n("使用 "),e("a",{href:"https://appops.rikka.app/",target:"_blank",rel:"noreferrer"},"App Ops"),n(" 在权限管理中手动授予 ACCESS_RESTRICTED_SETTINGS 权限")],-1)),l(s,{src:"0037.png"})])]),a[13]||(a[13]=e("h2",{id:"close_warn_dialog",tabindex:"-1"},[n("关闭无障碍警告弹窗 "),e("a",{class:"header-anchor",href:"#close_warn_dialog","aria-label":"Permalink to “关闭无障碍警告弹窗”"},"​")],-1)),a[14]||(a[14]=e("div",{class:"tip custom-block github-alert"},[e("p",{class:"custom-block-title"},"建议"),e("p",null,[n("授予 "),e("code",null,"写入安全设置权限"),n(" 后可自行开启无障碍, 而无需设置此项")])],-1)),a[15]||(a[15]=e("p",null,"这个方案不一定适用所有机型",-1)),a[16]||(a[16]=e("p",null,"大多数设备开启无障碍时都会出现 10s 的无障碍警告弹窗",-1)),a[17]||(a[17]=e("p",null,"若是只需要开启一次则无所谓但是如果开启次数比较多每次都有这个警告等待就很烦人了",-1)),l(t,{images:[["0004.png","0005.png"]]}),a[18]||(a[18]=e("p",null,[n("你可能已经看到这个界面还有一个开关, 也就是下方的 "),e("code",null,"快捷方式"),n(" 开关")],-1)),a[19]||(a[19]=e("p",null,"打开一次下面这个快捷方式开关后, 上面的的开启按钮就不会出现警告弹窗了, 但是你会发现屏幕侧边出现了一个应用小图标, 多数情况下我们并不需要这个图标",-1)),a[20]||(a[20]=e("p",null,'到无障碍界面-"无障碍"按钮-使用按钮或手势-点击切换为手势即可隐藏',-1)),a[21]||(a[21]=e("p",null,"以 Xiaomi HyperOS 为例子, 下面是完整的关闭弹窗流程截图",-1)),l(t,{images:[["0009.png","0010.png","0011.png","0012.png"]]}),a[22]||(a[22]=i(`<h2 id="adb_failed" tabindex="-1">adb 授权失败 <a class="header-anchor" href="#adb_failed" aria-label="Permalink to “adb 授权失败”">​</a></h2><p>在使用 adb 手动授予 <code>写入安全设置权限</code> 时可能会提示权限不够,具体报错如下:</p><div class="language-text"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span>adb shell pm grant li.songe.gkd android.permission.WRITE_SECURE_SETTINGS</span></span>
1
+ import{_ as o,I as r,c as d,o as c,aq as i,J as l,j as e,a as n,w as u}from"./chunks/framework.C9O3MI31.js";const x=JSON.parse('{"title":"常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/faq.md","filePath":"guide/faq.md","lastUpdated":1775561871000}'),g={name:"guide/faq.md"};function m(h,a,k,b,P,f){const s=r("GImg"),t=r("ImageTable"),p=r("NImageGroup");return c(),d("div",null,[a[4]||(a[4]=i('<h1 id="title" tabindex="-1">常见问题 <a class="header-anchor" href="#title" aria-label="Permalink to “常见问题”">​</a></h1><p>一些可能影响使用体验的问题和对应解决方案, 某些方案可能并不适用您的机型系统</p><p>如您有更好的方案或想对现有方案进行补充, 请点击底部 <code>为此页提供修改建议</code></p><h2 id="play-diff" tabindex="-1">渠道区别 <a class="header-anchor" href="#play-diff" aria-label="Permalink to “渠道区别”">​</a></h2><p>目前有两个渠道在使用,它们可互相安装覆盖,但存在区别</p><table tabindex="0"><thead><tr><th style="text-align:center;">渠道</th><th style="text-align:center;">下载方式</th><th style="text-align:center;">自更新逻辑</th><th style="text-align:center;"><a href="#restriction">受限制的设置</a></th><th style="text-align:center;">无障碍工具声明</th></tr></thead><tbody><tr><td style="text-align:center;">gkd</td><td style="text-align:center;"><a href="/guide/">官网/GitHub</a></td><td style="text-align:center;">弹窗更新(镜像加速)</td><td style="text-align:center;">可能受限</td><td style="text-align:center;">有</td></tr><tr><td style="text-align:center;">play</td><td style="text-align:center;"><a href="https://play.google.com/store/apps/details?id=li.songe.gkd" target="_blank" rel="noreferrer">Google Play</a></td><td style="text-align:center;">无(必须Google Play)</td><td style="text-align:center;">不会</td><td style="text-align:center;">无</td></tr></tbody></table><p>根据 <a href="https://support.google.com/googleplay/android-developer/answer/10964491?hl=zh-Hans" target="_blank" rel="noreferrer">Google Play 政策</a>,必须以 <strong>支持残障人士为主要用途</strong> 才能使用 <strong>无障碍工具声明</strong></p><p>如果没有这个声明,系统会隔段时间显示通知(<a href="https://github.com/orgs/gkd-kit/discussions/744" target="_blank" rel="noreferrer">discussions#744</a>),内容如下</p><p><code>查看权限设置(GKD可以查看和控制您的屏幕。点按即可查看。)</code></p><p>如果你无法忍受这个通知,切换到 gkd 渠道即可</p><h2 id="power" tabindex="-1">耗电说明 <a class="header-anchor" href="#power" aria-label="Permalink to “耗电说明”">​</a></h2><p>首先 GKD 默认情况下并不耗电,有的人以为关闭更新检测,关闭日志就能减少耗电,并不正确</p><p>真正的耗电在于 启用的规则 和 当前应用界面无障碍节点数量及无障碍事件刷新频率</p><p>如果想追求低耗电,那应该开启少量的规则,由于之前的默认规则数量有 1300+,很多人喜欢无脑开启规则</p><p>甚至有的用户同时开启多个订阅, 而这些订阅基本都 fork 自默认订阅, 这相当于同时开启多个重复规则</p><p>开启这么多规则,并且在这些规则匹配的界面使用手机,不耗电是不可能的</p><p>此外,某些软件如抖音的无障碍节点数量比较多,并且产生无障碍事件频率也比较高</p><p>长时间下使用此类软件的规则会比较耗电,请自行考虑后再启用</p><h2 id="shizuku" tabindex="-1">shizuku <a class="header-anchor" href="#shizuku" aria-label="Permalink to “shizuku”">​</a></h2><p>shizuku 是一个能让普通应用通过 ADB 或 Root 权限直接调用 Android 系统 API 的框架</p><p>简而言之, 授权 shizuku 后 GKD 可以调用更多系统 API 获取更多状态,启用更多优化</p><p>官方原版 <a href="https://github.com/RikkaApps/Shizuku" target="_blank" rel="noreferrer">RikkaApps/Shizuku</a> 已很久未有维护记录,issue/pr 也被垃圾机器人淹没</p><p>建议使用另一位开发者的分支项目 <a href="https://github.com/thedjchi/Shizuku" target="_blank" rel="noreferrer">thedjchi/Shizuku</a>,或<a href="https://github.com/thedjchi/Shizuku/releases/latest" target="_blank" rel="noreferrer">点击前往下载</a></p><h3 id="exact-activity" tabindex="-1">界面识别 <a class="header-anchor" href="#exact-activity" aria-label="Permalink to “界面识别”">​</a></h3><p>单纯靠无障碍提供的 API 无法准确判断当前处于应用的哪个子界面 (activityId)</p><p>在此种情况下, GKD 将运行当前应用的所有规则, 容易造成无效匹配和误触</p><p>授权 shizuku 后可以让 GKD 准确识别当前应用子界面</p><h3 id="forced-tap" tabindex="-1">强制点击 <a class="header-anchor" href="#forced-tap" aria-label="Permalink to “强制点击”">​</a></h3><p>使用无障碍 API 发出的点击事件 <code>clickCenter</code> 会被某些应用识别到, 导致点击表现无效</p><p>授权 shizuku 后可以让 GKD 发出的点击事件无法被应用识别到, 从而正常触发点击</p><h3 id="work-profile" tabindex="-1">工作空间 <a class="header-anchor" href="#work-profile" aria-label="Permalink to “工作空间”">​</a></h3><p>某些用户可能选择将应用安装到其他用户空间隔离</p><p>这导致 GKD 无法从当前应用列表识别到应用已安装</p><p>授权 shizuku 后可以让 GKD 识别到其他用户空间的应用</p><ul><li>只识别主空间未安装应用</li><li>只在主空间有应用变更行为时才全量更新用户空间应用列表</li></ul><p>如果不开启此项, 对于未安装的应用, 有以下影响</p><ul><li>全局规则 的内部配置禁用失效</li><li>应用规则 不会启用</li></ul><p>对于 <code>全局规则</code> 可使用手动编辑禁用, 添加 appId 到禁用列表后将生效</p><p>若要开启 <code>应用规则</code>, 在对应订阅-应用规则-显示未安装应用-打开右侧开关即可</p><details class="details custom-block"><summary>不生效原因</summary><p>这是因为某些订阅有将近 2k 个应用, 而一般用户最多使用到 200 个</p><p>如果将 未安装的应用 的应用规则也全部开启, 这将额外占用 1800 个应用的无效规则配置内存</p></details><h2 id="persistent" tabindex="-1">后台运行 <a class="header-anchor" href="#persistent" aria-label="Permalink to “后台运行”">​</a></h2><p>如何尽量保持后台运行不被系统暂停/杀死</p><ul><li>任务切换界面给 GKD 应用卡片加锁即可</li></ul><p>一般情况下, 使用此项即可正常后台运行, 如果不行请使用下面的步骤</p><ul><li>打开 GKD 首页, 开启 <code>常驻通知</code></li><li>允许后台活动, 关闭省电策略, 或者设置 GKD 的省电策略为无限制</li><li>允许 GKD 自启动</li></ul><p>某些系统如 MagicOS9 需要打开 <code>允许后台活动</code>, 否则 GKD 在后台时会被系统暂停执行</p>',46)),l(s,{src:"0038.jpg"}),a[5]||(a[5]=e("h2",{id:"restriction",tabindex:"-1"},[n("受限制的设置 "),e("a",{class:"header-anchor",href:"#restriction","aria-label":"Permalink to “受限制的设置”"},"​")],-1)),a[6]||(a[6]=e("p",null,"无障碍列表界面提示",-1)),a[7]||(a[7]=e("blockquote",null,[e("p",null,"受限制的设置(出于安全考虑,此设置目前不可用)")],-1)),a[8]||(a[8]=e("p",null,"或提示",-1)),a[9]||(a[9]=e("blockquote",null,[e("p",null,"系统已拒绝向此应用授予访问权限")],-1)),l(t,{images:[["0014.png","0039.jpg"]]}),a[10]||(a[10]=e("p",null,"这是因为某些系统对于 不在应用商店等可信任来源安装的 不能直接开启无障碍权限",-1)),a[11]||(a[11]=e("p",null,"解除步骤: GKD 应用信息 - 允许受限制的设置, 注意某些设备位置不太一样",-1)),e("table",null,[a[0]||(a[0]=e("thead",null,[e("tr",null,[e("th",{class:"text-center!"},[n("原生系统 "),e("br"),n(" 应用信息 - 右上角 - 允许受限制的设置")]),e("th",{class:"text-center!"},[n("小米系统 "),e("br"),n(" 应用信息 - 高级设置 - 允许受限制的设置")])])],-1)),e("tbody",null,[l(p,null,{default:u(()=>[e("tr",null,[e("td",null,[l(s,{src:"0016.png"})]),e("td",null,[l(s,{src:"0040.jpg"})])])]),_:1})])]),a[12]||(a[12]=i('<p>如果按步骤开启后 无障碍列表 仍然提示不可用, 可尝试 <strong>重启设备</strong></p><p>如果应用信息右上角没有 <code>允许受限制的设置</code> 选项, 请参考下一节方案</p><h2 id="unable_open_a11y" tabindex="-1">无法开启无障碍 <a class="header-anchor" href="#unable_open_a11y" aria-label="Permalink to “无法开启无障碍”">​</a></h2><p>某些系统如 ColorOS 有更严格的无障碍限制</p><p>如果你是其他来源安装或 GKD 内部更新后也会无法开启无障碍, 表现以下行为</p><ul><li>提示 受限制的设置, 但是没有找到 允许受限制的设置 的选项</li><li>不提示 受限制的设置, 无障碍开启按钮可点击, 但点击后没有响应, 无法开启</li></ul><p>可以通过以下方式解决, 可在 设置 - 关于 - 分享应用 获取 APK 文件</p>',7)),e("ul",null,[a[2]||(a[2]=e("li",null,[e("p",null,"使用系统信任的方式进行安装, 例如在系统文件管理中查看 APK 文件后点击安装, 是覆盖安装无需卸载")],-1)),a[3]||(a[3]=e("li",null,[e("p",null,[n("如果使用系统安装器, 但是在冻结了应用安装器 "),e("code",null,"com.oplus.appdetail"),n(" 状态下安装的 APK, 需解冻后重新安装")])],-1)),e("li",null,[a[1]||(a[1]=e("p",null,[n("使用 "),e("a",{href:"https://appops.rikka.app/",target:"_blank",rel:"noreferrer"},"App Ops"),n(" 在权限管理中手动授予 ACCESS_RESTRICTED_SETTINGS 权限")],-1)),l(s,{src:"0037.png"})])]),a[13]||(a[13]=e("h2",{id:"close_warn_dialog",tabindex:"-1"},[n("关闭无障碍警告弹窗 "),e("a",{class:"header-anchor",href:"#close_warn_dialog","aria-label":"Permalink to “关闭无障碍警告弹窗”"},"​")],-1)),a[14]||(a[14]=e("div",{class:"tip custom-block github-alert"},[e("p",{class:"custom-block-title"},"建议"),e("p",null,[n("授予 "),e("code",null,"写入安全设置权限"),n(" 后可自行开启无障碍, 而无需设置此项")])],-1)),a[15]||(a[15]=e("p",null,"这个方案不一定适用所有机型",-1)),a[16]||(a[16]=e("p",null,"大多数设备开启无障碍时都会出现 10s 的无障碍警告弹窗",-1)),a[17]||(a[17]=e("p",null,"若是只需要开启一次则无所谓但是如果开启次数比较多每次都有这个警告等待就很烦人了",-1)),l(t,{images:[["0004.png","0005.png"]]}),a[18]||(a[18]=e("p",null,[n("你可能已经看到这个界面还有一个开关, 也就是下方的 "),e("code",null,"快捷方式"),n(" 开关")],-1)),a[19]||(a[19]=e("p",null,"打开一次下面这个快捷方式开关后, 上面的的开启按钮就不会出现警告弹窗了, 但是你会发现屏幕侧边出现了一个应用小图标, 多数情况下我们并不需要这个图标",-1)),a[20]||(a[20]=e("p",null,'到无障碍界面-"无障碍"按钮-使用按钮或手势-点击切换为手势即可隐藏',-1)),a[21]||(a[21]=e("p",null,"以 Xiaomi HyperOS 为例子, 下面是完整的关闭弹窗流程截图",-1)),l(t,{images:[["0009.png","0010.png","0011.png","0012.png"]]}),a[22]||(a[22]=i(`<h2 id="adb_failed" tabindex="-1">adb 授权失败 <a class="header-anchor" href="#adb_failed" aria-label="Permalink to “adb 授权失败”">​</a></h2><p>在使用 adb 手动授予 <code>写入安全设置权限</code> 时可能会提示权限不够,具体报错如下:</p><div class="language-text"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span>adb shell pm grant li.songe.gkd android.permission.WRITE_SECURE_SETTINGS</span></span>
2
2
  <span class="line"><span></span></span>
3
3
  <span class="line"><span>Exception occurred while executing &#39;grant&#39;:</span></span>
4
4
  <span class="line"><span>java.lang.SecurityException: grantRuntimePermission: Neither user 2000 nor current process has android.permission.GRANT_RUNTIME_PERMISSIONS.</span></span>
@@ -1 +1 @@
1
- import{_ as o,I as r,c as d,o as c,aq as i,J as l,j as e,a as n,w as u}from"./chunks/framework.C9O3MI31.js";const x=JSON.parse('{"title":"常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/faq.md","filePath":"guide/faq.md","lastUpdated":1773041507000}'),g={name:"guide/faq.md"};function m(h,a,k,b,P,f){const s=r("GImg"),t=r("ImageTable"),p=r("NImageGroup");return c(),d("div",null,[a[4]||(a[4]=i("",46)),l(s,{src:"0038.jpg"}),a[5]||(a[5]=e("h2",{id:"restriction",tabindex:"-1"},[n("受限制的设置 "),e("a",{class:"header-anchor",href:"#restriction","aria-label":"Permalink to “受限制的设置”"},"​")],-1)),a[6]||(a[6]=e("p",null,"无障碍列表界面提示",-1)),a[7]||(a[7]=e("blockquote",null,[e("p",null,"受限制的设置(出于安全考虑,此设置目前不可用)")],-1)),a[8]||(a[8]=e("p",null,"或提示",-1)),a[9]||(a[9]=e("blockquote",null,[e("p",null,"系统已拒绝向此应用授予访问权限")],-1)),l(t,{images:[["0014.png","0039.jpg"]]}),a[10]||(a[10]=e("p",null,"这是因为某些系统对于 不在应用商店等可信任来源安装的 不能直接开启无障碍权限",-1)),a[11]||(a[11]=e("p",null,"解除步骤: GKD 应用信息 - 允许受限制的设置, 注意某些设备位置不太一样",-1)),e("table",null,[a[0]||(a[0]=e("thead",null,[e("tr",null,[e("th",{class:"text-center!"},[n("原生系统 "),e("br"),n(" 应用信息 - 右上角 - 允许受限制的设置")]),e("th",{class:"text-center!"},[n("小米系统 "),e("br"),n(" 应用信息 - 高级设置 - 允许受限制的设置")])])],-1)),e("tbody",null,[l(p,null,{default:u(()=>[e("tr",null,[e("td",null,[l(s,{src:"0016.png"})]),e("td",null,[l(s,{src:"0040.jpg"})])])]),_:1})])]),a[12]||(a[12]=i("",7)),e("ul",null,[a[2]||(a[2]=e("li",null,[e("p",null,"使用系统信任的方式进行安装, 例如在系统文件管理中查看 APK 文件后点击安装, 是覆盖安装无需卸载")],-1)),a[3]||(a[3]=e("li",null,[e("p",null,[n("如果使用系统安装器, 但是在冻结了应用安装器 "),e("code",null,"com.oplus.appdetail"),n(" 状态下安装的 APK, 需解冻后重新安装")])],-1)),e("li",null,[a[1]||(a[1]=e("p",null,[n("使用 "),e("a",{href:"https://appops.rikka.app/",target:"_blank",rel:"noreferrer"},"App Ops"),n(" 在权限管理中手动授予 ACCESS_RESTRICTED_SETTINGS 权限")],-1)),l(s,{src:"0037.png"})])]),a[13]||(a[13]=e("h2",{id:"close_warn_dialog",tabindex:"-1"},[n("关闭无障碍警告弹窗 "),e("a",{class:"header-anchor",href:"#close_warn_dialog","aria-label":"Permalink to “关闭无障碍警告弹窗”"},"​")],-1)),a[14]||(a[14]=e("div",{class:"tip custom-block github-alert"},[e("p",{class:"custom-block-title"},"建议"),e("p",null,[n("授予 "),e("code",null,"写入安全设置权限"),n(" 后可自行开启无障碍, 而无需设置此项")])],-1)),a[15]||(a[15]=e("p",null,"这个方案不一定适用所有机型",-1)),a[16]||(a[16]=e("p",null,"大多数设备开启无障碍时都会出现 10s 的无障碍警告弹窗",-1)),a[17]||(a[17]=e("p",null,"若是只需要开启一次则无所谓但是如果开启次数比较多每次都有这个警告等待就很烦人了",-1)),l(t,{images:[["0004.png","0005.png"]]}),a[18]||(a[18]=e("p",null,[n("你可能已经看到这个界面还有一个开关, 也就是下方的 "),e("code",null,"快捷方式"),n(" 开关")],-1)),a[19]||(a[19]=e("p",null,"打开一次下面这个快捷方式开关后, 上面的的开启按钮就不会出现警告弹窗了, 但是你会发现屏幕侧边出现了一个应用小图标, 多数情况下我们并不需要这个图标",-1)),a[20]||(a[20]=e("p",null,'到无障碍界面-"无障碍"按钮-使用按钮或手势-点击切换为手势即可隐藏',-1)),a[21]||(a[21]=e("p",null,"以 Xiaomi HyperOS 为例子, 下面是完整的关闭弹窗流程截图",-1)),l(t,{images:[["0009.png","0010.png","0011.png","0012.png"]]}),a[22]||(a[22]=i("",6))])}const v=o(g,[["render",m]]);export{x as __pageData,v as default};
1
+ import{_ as o,I as r,c as d,o as c,aq as i,J as l,j as e,a as n,w as u}from"./chunks/framework.C9O3MI31.js";const x=JSON.parse('{"title":"常见问题","description":"","frontmatter":{},"headers":[],"relativePath":"guide/faq.md","filePath":"guide/faq.md","lastUpdated":1775561871000}'),g={name:"guide/faq.md"};function m(h,a,k,b,P,f){const s=r("GImg"),t=r("ImageTable"),p=r("NImageGroup");return c(),d("div",null,[a[4]||(a[4]=i("",46)),l(s,{src:"0038.jpg"}),a[5]||(a[5]=e("h2",{id:"restriction",tabindex:"-1"},[n("受限制的设置 "),e("a",{class:"header-anchor",href:"#restriction","aria-label":"Permalink to “受限制的设置”"},"​")],-1)),a[6]||(a[6]=e("p",null,"无障碍列表界面提示",-1)),a[7]||(a[7]=e("blockquote",null,[e("p",null,"受限制的设置(出于安全考虑,此设置目前不可用)")],-1)),a[8]||(a[8]=e("p",null,"或提示",-1)),a[9]||(a[9]=e("blockquote",null,[e("p",null,"系统已拒绝向此应用授予访问权限")],-1)),l(t,{images:[["0014.png","0039.jpg"]]}),a[10]||(a[10]=e("p",null,"这是因为某些系统对于 不在应用商店等可信任来源安装的 不能直接开启无障碍权限",-1)),a[11]||(a[11]=e("p",null,"解除步骤: GKD 应用信息 - 允许受限制的设置, 注意某些设备位置不太一样",-1)),e("table",null,[a[0]||(a[0]=e("thead",null,[e("tr",null,[e("th",{class:"text-center!"},[n("原生系统 "),e("br"),n(" 应用信息 - 右上角 - 允许受限制的设置")]),e("th",{class:"text-center!"},[n("小米系统 "),e("br"),n(" 应用信息 - 高级设置 - 允许受限制的设置")])])],-1)),e("tbody",null,[l(p,null,{default:u(()=>[e("tr",null,[e("td",null,[l(s,{src:"0016.png"})]),e("td",null,[l(s,{src:"0040.jpg"})])])]),_:1})])]),a[12]||(a[12]=i("",7)),e("ul",null,[a[2]||(a[2]=e("li",null,[e("p",null,"使用系统信任的方式进行安装, 例如在系统文件管理中查看 APK 文件后点击安装, 是覆盖安装无需卸载")],-1)),a[3]||(a[3]=e("li",null,[e("p",null,[n("如果使用系统安装器, 但是在冻结了应用安装器 "),e("code",null,"com.oplus.appdetail"),n(" 状态下安装的 APK, 需解冻后重新安装")])],-1)),e("li",null,[a[1]||(a[1]=e("p",null,[n("使用 "),e("a",{href:"https://appops.rikka.app/",target:"_blank",rel:"noreferrer"},"App Ops"),n(" 在权限管理中手动授予 ACCESS_RESTRICTED_SETTINGS 权限")],-1)),l(s,{src:"0037.png"})])]),a[13]||(a[13]=e("h2",{id:"close_warn_dialog",tabindex:"-1"},[n("关闭无障碍警告弹窗 "),e("a",{class:"header-anchor",href:"#close_warn_dialog","aria-label":"Permalink to “关闭无障碍警告弹窗”"},"​")],-1)),a[14]||(a[14]=e("div",{class:"tip custom-block github-alert"},[e("p",{class:"custom-block-title"},"建议"),e("p",null,[n("授予 "),e("code",null,"写入安全设置权限"),n(" 后可自行开启无障碍, 而无需设置此项")])],-1)),a[15]||(a[15]=e("p",null,"这个方案不一定适用所有机型",-1)),a[16]||(a[16]=e("p",null,"大多数设备开启无障碍时都会出现 10s 的无障碍警告弹窗",-1)),a[17]||(a[17]=e("p",null,"若是只需要开启一次则无所谓但是如果开启次数比较多每次都有这个警告等待就很烦人了",-1)),l(t,{images:[["0004.png","0005.png"]]}),a[18]||(a[18]=e("p",null,[n("你可能已经看到这个界面还有一个开关, 也就是下方的 "),e("code",null,"快捷方式"),n(" 开关")],-1)),a[19]||(a[19]=e("p",null,"打开一次下面这个快捷方式开关后, 上面的的开启按钮就不会出现警告弹窗了, 但是你会发现屏幕侧边出现了一个应用小图标, 多数情况下我们并不需要这个图标",-1)),a[20]||(a[20]=e("p",null,'到无障碍界面-"无障碍"按钮-使用按钮或手势-点击切换为手势即可隐藏',-1)),a[21]||(a[21]=e("p",null,"以 Xiaomi HyperOS 为例子, 下面是完整的关闭弹窗流程截图",-1)),l(t,{images:[["0009.png","0010.png","0011.png","0012.png"]]}),a[22]||(a[22]=i("",6))])}const v=o(g,[["render",m]]);export{x as __pageData,v as default};
@@ -1 +1 @@
1
- import{_ as i,I as l,c as d,o as p,j as a,J as r,aq as g,a as t,w as m}from"./chunks/framework.C9O3MI31.js";const T=JSON.parse('{"title":"开始使用","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md","lastUpdated":1773041507000}'),c={name:"guide/index.md"};function u(f,e,_,b,h,k){const s=l("GkdOnly"),n=l("ApkTable"),o=l("ImageTable");return p(),d("div",null,[e[1]||(e[1]=a("h1",{id:"title",tabindex:"-1"},[t("开始使用 "),a("a",{class:"header-anchor",href:"#title","aria-label":"Permalink to “开始使用”"},"​")],-1)),e[2]||(e[2]=a("h2",{id:"install",tabindex:"-1"},[t("安装 "),a("a",{class:"header-anchor",href:"#install","aria-label":"Permalink to “安装”"},"​")],-1)),r(s,null,{default:m(()=>e[0]||(e[0]=[a("div",{class:"tip custom-block github-alert"},[a("p",{class:"custom-block-title"},"下载提示"),a("p",null,"检测到您在应用内无法下载 APK,请点击右上角-外部打开后下载")],-1)])),_:1}),r(n),e[3]||(e[3]=g('<details class="details custom-block"><summary>手机浏览器下载失败?</summary><p>某些手机浏览器存在自定义拦截会导致下载失败, 建议使用 <a href="https://viayoo.com" target="_blank" rel="noreferrer">Via</a> 浏览器下载</p></details><p>其它下载方式</p><ul><li><a href="https://play.google.com/store/apps/details?id=li.songe.gkd" target="_blank" rel="noreferrer">Google Play</a>   <a href="./faq#play-diff">区别</a></li><li><a href="https://github.com/gkd-kit/gkd/releases" target="_blank" rel="noreferrer">Github Releases</a></li></ul><p>下载完毕后, 在您的 Android 手机上安装并打开</p><h2 id="usage" tabindex="-1">使用 <a class="header-anchor" href="#usage" aria-label="Permalink to “使用”">​</a></h2><p>打开后进入 GKD 的首页, 要想 GKD 正常工作需要授权无障碍权限</p><p>点击无障碍权限右侧的 <code>授权</code> 按钮即可前往设置的无障碍界面授权</p><p>以 Xiaomi HyperOS 为例, 下面为完整的授权流程截图</p>',8)),r(o,{images:[["0001.png","0002.png","0003.png","0004.png"],["0005.png","0006.png","0007.png","0008.png"]]}),e[4]||(e[4]=a("p",null,[t("如遇到问题可在 "),a("a",{href:"/guide/faq"},"常见问题"),t(" 查阅解决方案")],-1))])}const y=i(c,[["render",u]]);export{T as __pageData,y as default};
1
+ import{_ as i,I as l,c as d,o as p,j as a,J as r,aq as g,a as t,w as m}from"./chunks/framework.C9O3MI31.js";const T=JSON.parse('{"title":"开始使用","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md","lastUpdated":1775561871000}'),c={name:"guide/index.md"};function u(f,e,_,b,h,k){const s=l("GkdOnly"),n=l("ApkTable"),o=l("ImageTable");return p(),d("div",null,[e[1]||(e[1]=a("h1",{id:"title",tabindex:"-1"},[t("开始使用 "),a("a",{class:"header-anchor",href:"#title","aria-label":"Permalink to “开始使用”"},"​")],-1)),e[2]||(e[2]=a("h2",{id:"install",tabindex:"-1"},[t("安装 "),a("a",{class:"header-anchor",href:"#install","aria-label":"Permalink to “安装”"},"​")],-1)),r(s,null,{default:m(()=>e[0]||(e[0]=[a("div",{class:"tip custom-block github-alert"},[a("p",{class:"custom-block-title"},"下载提示"),a("p",null,"检测到您在应用内无法下载 APK,请点击右上角-外部打开后下载")],-1)])),_:1}),r(n),e[3]||(e[3]=g('<details class="details custom-block"><summary>手机浏览器下载失败?</summary><p>某些手机浏览器存在自定义拦截会导致下载失败, 建议使用 <a href="https://viayoo.com" target="_blank" rel="noreferrer">Via</a> 浏览器下载</p></details><p>其它下载方式</p><ul><li><a href="https://play.google.com/store/apps/details?id=li.songe.gkd" target="_blank" rel="noreferrer">Google Play</a>   <a href="./faq#play-diff">区别</a></li><li><a href="https://github.com/gkd-kit/gkd/releases" target="_blank" rel="noreferrer">Github Releases</a></li></ul><p>下载完毕后, 在您的 Android 手机上安装并打开</p><h2 id="usage" tabindex="-1">使用 <a class="header-anchor" href="#usage" aria-label="Permalink to “使用”">​</a></h2><p>打开后进入 GKD 的首页, 要想 GKD 正常工作需要授权无障碍权限</p><p>点击无障碍权限右侧的 <code>授权</code> 按钮即可前往设置的无障碍界面授权</p><p>以 Xiaomi HyperOS 为例, 下面为完整的授权流程截图</p>',8)),r(o,{images:[["0001.png","0002.png","0003.png","0004.png"],["0005.png","0006.png","0007.png","0008.png"]]}),e[4]||(e[4]=a("p",null,[t("如遇到问题可在 "),a("a",{href:"/guide/faq"},"常见问题"),t(" 查阅解决方案")],-1))])}const y=i(c,[["render",u]]);export{T as __pageData,y as default};
@@ -1 +1 @@
1
- import{_ as i,I as l,c as d,o as p,j as a,J as r,aq as g,a as t,w as m}from"./chunks/framework.C9O3MI31.js";const T=JSON.parse('{"title":"开始使用","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md","lastUpdated":1773041507000}'),c={name:"guide/index.md"};function u(f,e,_,b,h,k){const s=l("GkdOnly"),n=l("ApkTable"),o=l("ImageTable");return p(),d("div",null,[e[1]||(e[1]=a("h1",{id:"title",tabindex:"-1"},[t("开始使用 "),a("a",{class:"header-anchor",href:"#title","aria-label":"Permalink to “开始使用”"},"​")],-1)),e[2]||(e[2]=a("h2",{id:"install",tabindex:"-1"},[t("安装 "),a("a",{class:"header-anchor",href:"#install","aria-label":"Permalink to “安装”"},"​")],-1)),r(s,null,{default:m(()=>e[0]||(e[0]=[a("div",{class:"tip custom-block github-alert"},[a("p",{class:"custom-block-title"},"下载提示"),a("p",null,"检测到您在应用内无法下载 APK,请点击右上角-外部打开后下载")],-1)])),_:1}),r(n),e[3]||(e[3]=g("",8)),r(o,{images:[["0001.png","0002.png","0003.png","0004.png"],["0005.png","0006.png","0007.png","0008.png"]]}),e[4]||(e[4]=a("p",null,[t("如遇到问题可在 "),a("a",{href:"/guide/faq"},"常见问题"),t(" 查阅解决方案")],-1))])}const y=i(c,[["render",u]]);export{T as __pageData,y as default};
1
+ import{_ as i,I as l,c as d,o as p,j as a,J as r,aq as g,a as t,w as m}from"./chunks/framework.C9O3MI31.js";const T=JSON.parse('{"title":"开始使用","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md","lastUpdated":1775561871000}'),c={name:"guide/index.md"};function u(f,e,_,b,h,k){const s=l("GkdOnly"),n=l("ApkTable"),o=l("ImageTable");return p(),d("div",null,[e[1]||(e[1]=a("h1",{id:"title",tabindex:"-1"},[t("开始使用 "),a("a",{class:"header-anchor",href:"#title","aria-label":"Permalink to “开始使用”"},"​")],-1)),e[2]||(e[2]=a("h2",{id:"install",tabindex:"-1"},[t("安装 "),a("a",{class:"header-anchor",href:"#install","aria-label":"Permalink to “安装”"},"​")],-1)),r(s,null,{default:m(()=>e[0]||(e[0]=[a("div",{class:"tip custom-block github-alert"},[a("p",{class:"custom-block-title"},"下载提示"),a("p",null,"检测到您在应用内无法下载 APK,请点击右上角-外部打开后下载")],-1)])),_:1}),r(n),e[3]||(e[3]=g("",8)),r(o,{images:[["0001.png","0002.png","0003.png","0004.png"],["0005.png","0006.png","0007.png","0008.png"]]}),e[4]||(e[4]=a("p",null,[t("如遇到问题可在 "),a("a",{href:"/guide/faq"},"常见问题"),t(" 查阅解决方案")],-1))])}const y=i(c,[["render",u]]);export{T as __pageData,y as default};
@@ -1 +1 @@
1
- import{_ as d,c as e,o,aq as a}from"./chunks/framework.C9O3MI31.js";const g=JSON.parse('{"title":"属性方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/node.md","filePath":"guide/node.md","lastUpdated":1773041507000}'),r={name:"guide/node.md"};function c(n,t,i,l,h,b){return o(),e("div",null,t[0]||(t[0]=[a('<h1 id="title" tabindex="-1">属性方法 <a class="header-anchor" href="#title" aria-label="Permalink to “属性方法”">​</a></h1><p>此章节介绍各个类型可用的属性及其方法</p><h2 id="null" tabindex="-1">null <a class="header-anchor" href="#null" aria-label="Permalink to “null”">​</a></h2><div class="note custom-block github-alert"><p class="custom-block-title">提示</p><p><code>null</code> 无任何属性方法, 并且在无特殊说明时, 属性方法当调用者或者参数是 <code>null</code> 时, 均返回 <code>null</code></p></div><p>当 <code>name</code> 是 <code>null</code> 时, <code>name.length</code> 为 <code>null</code></p><p>当 <code>parent</code> 是 <code>null</code> 时, <code>parent.getChild(0)</code> 为 <code>null</code></p><p>当 <code>index</code> 是 <code>null</code> 时, <code>parent.getChild(index)</code> 为 <code>null</code></p><h2 id="boolean" tabindex="-1">boolean <a class="header-anchor" href="#boolean" aria-label="Permalink to “boolean”">​</a></h2><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>toInt</td><td></td><td><code>int</code></td><td>转为 0 或 1</td></tr><tr><td>or</td><td><code>boolean</code></td><td><code>boolean</code></td><td>a || b</td></tr><tr><td>and</td><td><code>boolean</code></td><td><code>boolean</code></td><td>a &amp;&amp; b</td></tr><tr><td>not</td><td></td><td><code>boolean</code></td><td>!a</td></tr><tr><td>ifElse</td><td><code>T</code>, <code>T</code></td><td><code>T</code></td><td>if(a) T else T <br> T 是任意类型, 两个参数均支持为 null</td></tr></tbody></table><h2 id="int" tabindex="-1">int <a class="header-anchor" href="#int" aria-label="Permalink to “int”">​</a></h2><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>toString</td><td></td><td><a href="#string"><code>string</code></a></td><td>转为10进制字符串</td></tr><tr><td>toString</td><td><code>int</code></td><td><code>string</code></td><td>转为对应进制的字符串</td></tr><tr><td>plus</td><td><code>int</code></td><td><code>string</code></td><td>加上</td></tr><tr><td>minus</td><td><code>int</code></td><td><code>string</code></td><td>减去</td></tr><tr><td>times</td><td><code>int</code></td><td><code>string</code></td><td>乘以</td></tr><tr><td>div</td><td><code>int</code></td><td><code>string</code></td><td>除以</td></tr><tr><td>rem</td><td><code>int</code></td><td><code>string</code></td><td>取余</td></tr><tr><td>more</td><td><code>int</code></td><td><a href="#boolean"><code>boolean</code></a></td><td>a &gt; b</td></tr><tr><td>moreEqual</td><td><code>int</code></td><td><code>boolean</code></td><td>a &gt;= b</td></tr><tr><td>less</td><td><code>int</code></td><td><code>boolean</code></td><td>a &lt; b</td></tr><tr><td>lessEqual</td><td><code>int</code></td><td><code>boolean</code></td><td>a &lt;= b</td></tr></tbody></table><h2 id="string" tabindex="-1">string <a class="header-anchor" href="#string" aria-label="Permalink to “string”">​</a></h2><table tabindex="0"><thead><tr><th>标识符</th><th>属性类型</th><th>描述</th></tr></thead><tbody><tr><td>length</td><td><a href="#int"><code>int</code></a></td><td>字符串长度</td></tr></tbody></table><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>get</td><td><a href="#int"><code>int</code></a></td><td><code>string</code></td><td>获取对应索引字符串</td></tr><tr><td>at</td><td><code>int</code></td><td><code>string</code></td><td>同上,但是参数传负数时从最后一个字符取</td></tr><tr><td>substring</td><td><code>int</code></td><td><code>string</code></td><td>截取指定索引到结尾字符串</td></tr><tr><td>substring</td><td><code>int</code>,<code>int</code></td><td><code>string</code></td><td>截取指定间隔字符串</td></tr><tr><td>toInt</td><td></td><td><code>int</code></td><td>转为10进制数字</td></tr><tr><td>toInt</td><td><code>int</code></td><td><code>int</code></td><td>转为指定进制的数字</td></tr><tr><td>indexOf</td><td><code>string</code></td><td><code>int</code></td><td>查找指定字符串的索引</td></tr><tr><td>indexOf</td><td><code>string</code>,<code>int</code></td><td><code>int</code></td><td>从指定索引开始查找指定字符串的索引</td></tr></tbody></table><h2 id="node" tabindex="-1">node <a class="header-anchor" href="#node" aria-label="Permalink to “node”">​</a></h2><div class="important custom-block github-alert"><p class="custom-block-title">重要提示</p><p>此类型下以 _ 开头的属性只能在网页快照调试工具上使用, 真机不可用</p></div><table tabindex="0"><thead><tr><th>标识符</th><th>属性类型</th><th>描述</th></tr></thead><tbody><tr><td>_id</td><td><a href="#int"><code>int</code></a></td><td></td></tr><tr><td>_pid</td><td><code>int</code></td><td></td></tr><tr><td>id</td><td><a href="#string"><code>string</code></a></td><td></td></tr><tr><td>vid</td><td><code>string</code></td><td></td></tr><tr><td>name</td><td><code>string</code></td><td></td></tr><tr><td>text</td><td><code>string</code></td><td></td></tr><tr><td>desc</td><td><code>string</code></td><td></td></tr><tr><td>clickable</td><td><code>boolean</code></td><td></td></tr><tr><td>focusable</td><td><code>boolean</code></td><td></td></tr><tr><td>checkable</td><td><code>boolean</code></td><td></td></tr><tr><td>checked</td><td><code>boolean</code></td><td></td></tr><tr><td>editable</td><td><code>boolean</code></td><td></td></tr><tr><td>longClickable</td><td><code>boolean</code></td><td></td></tr><tr><td>visibleToUser</td><td><code>boolean</code></td><td></td></tr><tr><td>left</td><td><code>int</code></td><td></td></tr><tr><td>top</td><td><code>int</code></td><td></td></tr><tr><td>right</td><td><code>int</code></td><td></td></tr><tr><td>bottom</td><td><code>int</code></td><td></td></tr><tr><td>width</td><td><code>int</code></td><td></td></tr><tr><td>height</td><td><code>int</code></td><td></td></tr><tr><td>childCount</td><td><code>int</code></td><td></td></tr><tr><td>index</td><td><code>int</code></td><td></td></tr><tr><td>depth</td><td><code>int</code></td><td></td></tr><tr><td>parent</td><td><a href="#node"><code>node</code></a></td><td>获取父节点</td></tr></tbody></table><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>getChild</td><td><code>int</code></td><td><a href="#node"><code>node</code></a></td><td>获取指定索引的子节点</td></tr></tbody></table><h2 id="context" tabindex="-1">context <a class="header-anchor" href="#context" aria-label="Permalink to “context”">​</a></h2><p>context 具有 <a href="#node">node</a> 的所有属性方法, 下面只介绍额外属性方法</p><table tabindex="0"><thead><tr><th>标识符</th><th>属性类型</th><th>描述</th></tr></thead><tbody><tr><td>prev</td><td><a href="#context"><code>context</code></a></td><td>右侧属性选择器的节点上下文 <br> 最右侧的 prev=null</td></tr><tr><td>current</td><td><a href="#node"><code>node</code></a></td><td>当前节点 <br> current.id=id</td></tr></tbody></table><p>示例</p><div class="language-text"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span>FrameLayout[prev.name$=&#39;ImageView&#39;] &gt; ImageView[current.name=name]</span></span></code></pre></div><p>中的 prev 就是 FrameLayout 右侧的 ImageView, current 就是 ImageView</p><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>getPrev</td><td>int</td><td><a href="#context"><code>context</code></a></td><td>快捷获取深层 prev <br> getPrev(0) -&gt; prev <br> getPrev(1) -&gt; prev.prev <br> getPrev(2) -&gt; prev.prev.prev</td></tr></tbody></table><h2 id="global" tabindex="-1">global <a class="header-anchor" href="#global" aria-label="Permalink to “global”">​</a></h2><p>global 具有 <a href="#context">context</a> 的所有属性方法, 并且没有任何属性方法能获取 global 的引用, 下面只介绍额外属性方法</p><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>equal</td><td><code>T</code>, <code>T</code></td><td><a href="#boolean"><code>boolean</code></a></td><td>a==b <br> T 是任意类型, a,b 允许 null</td></tr><tr><td>notEqual</td><td><code>T</code>, <code>T</code></td><td><code>boolean</code></td><td>a!=b</td></tr></tbody></table><p>示例</p><div class="language-text"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span>[name=&#39;&#39;][prev.name=&#39;&#39;][current.name=&#39;&#39;][parent.name=&#39;&#39;]</span></span></code></pre></div><ul><li>第一个 <code>name</code> 来自 <a href="#global">global</a>, 实际上任何 <code>xxx</code>/<code>xxx()</code> 都来自 global</li><li>第二个 <code>prev.name</code> 来自 <a href="#context">context</a></li><li>后续的 <code>current.name</code>/<code>parent.name</code> 都来自 <a href="#node">node</a></li></ul>',31)]))}const p=d(r,[["render",c]]);export{g as __pageData,p as default};
1
+ import{_ as d,c as e,o,aq as a}from"./chunks/framework.C9O3MI31.js";const g=JSON.parse('{"title":"属性方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/node.md","filePath":"guide/node.md","lastUpdated":1775561871000}'),r={name:"guide/node.md"};function c(n,t,i,l,h,b){return o(),e("div",null,t[0]||(t[0]=[a('<h1 id="title" tabindex="-1">属性方法 <a class="header-anchor" href="#title" aria-label="Permalink to “属性方法”">​</a></h1><p>此章节介绍各个类型可用的属性及其方法</p><h2 id="null" tabindex="-1">null <a class="header-anchor" href="#null" aria-label="Permalink to “null”">​</a></h2><div class="note custom-block github-alert"><p class="custom-block-title">提示</p><p><code>null</code> 无任何属性方法, 并且在无特殊说明时, 属性方法当调用者或者参数是 <code>null</code> 时, 均返回 <code>null</code></p></div><p>当 <code>name</code> 是 <code>null</code> 时, <code>name.length</code> 为 <code>null</code></p><p>当 <code>parent</code> 是 <code>null</code> 时, <code>parent.getChild(0)</code> 为 <code>null</code></p><p>当 <code>index</code> 是 <code>null</code> 时, <code>parent.getChild(index)</code> 为 <code>null</code></p><h2 id="boolean" tabindex="-1">boolean <a class="header-anchor" href="#boolean" aria-label="Permalink to “boolean”">​</a></h2><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>toInt</td><td></td><td><code>int</code></td><td>转为 0 或 1</td></tr><tr><td>or</td><td><code>boolean</code></td><td><code>boolean</code></td><td>a || b</td></tr><tr><td>and</td><td><code>boolean</code></td><td><code>boolean</code></td><td>a &amp;&amp; b</td></tr><tr><td>not</td><td></td><td><code>boolean</code></td><td>!a</td></tr><tr><td>ifElse</td><td><code>T</code>, <code>T</code></td><td><code>T</code></td><td>if(a) T else T <br> T 是任意类型, 两个参数均支持为 null</td></tr></tbody></table><h2 id="int" tabindex="-1">int <a class="header-anchor" href="#int" aria-label="Permalink to “int”">​</a></h2><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>toString</td><td></td><td><a href="#string"><code>string</code></a></td><td>转为10进制字符串</td></tr><tr><td>toString</td><td><code>int</code></td><td><code>string</code></td><td>转为对应进制的字符串</td></tr><tr><td>plus</td><td><code>int</code></td><td><code>string</code></td><td>加上</td></tr><tr><td>minus</td><td><code>int</code></td><td><code>string</code></td><td>减去</td></tr><tr><td>times</td><td><code>int</code></td><td><code>string</code></td><td>乘以</td></tr><tr><td>div</td><td><code>int</code></td><td><code>string</code></td><td>除以</td></tr><tr><td>rem</td><td><code>int</code></td><td><code>string</code></td><td>取余</td></tr><tr><td>more</td><td><code>int</code></td><td><a href="#boolean"><code>boolean</code></a></td><td>a &gt; b</td></tr><tr><td>moreEqual</td><td><code>int</code></td><td><code>boolean</code></td><td>a &gt;= b</td></tr><tr><td>less</td><td><code>int</code></td><td><code>boolean</code></td><td>a &lt; b</td></tr><tr><td>lessEqual</td><td><code>int</code></td><td><code>boolean</code></td><td>a &lt;= b</td></tr></tbody></table><h2 id="string" tabindex="-1">string <a class="header-anchor" href="#string" aria-label="Permalink to “string”">​</a></h2><table tabindex="0"><thead><tr><th>标识符</th><th>属性类型</th><th>描述</th></tr></thead><tbody><tr><td>length</td><td><a href="#int"><code>int</code></a></td><td>字符串长度</td></tr></tbody></table><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>get</td><td><a href="#int"><code>int</code></a></td><td><code>string</code></td><td>获取对应索引字符串</td></tr><tr><td>at</td><td><code>int</code></td><td><code>string</code></td><td>同上,但是参数传负数时从最后一个字符取</td></tr><tr><td>substring</td><td><code>int</code></td><td><code>string</code></td><td>截取指定索引到结尾字符串</td></tr><tr><td>substring</td><td><code>int</code>,<code>int</code></td><td><code>string</code></td><td>截取指定间隔字符串</td></tr><tr><td>toInt</td><td></td><td><code>int</code></td><td>转为10进制数字</td></tr><tr><td>toInt</td><td><code>int</code></td><td><code>int</code></td><td>转为指定进制的数字</td></tr><tr><td>indexOf</td><td><code>string</code></td><td><code>int</code></td><td>查找指定字符串的索引</td></tr><tr><td>indexOf</td><td><code>string</code>,<code>int</code></td><td><code>int</code></td><td>从指定索引开始查找指定字符串的索引</td></tr></tbody></table><h2 id="node" tabindex="-1">node <a class="header-anchor" href="#node" aria-label="Permalink to “node”">​</a></h2><div class="important custom-block github-alert"><p class="custom-block-title">重要提示</p><p>此类型下以 _ 开头的属性只能在网页快照调试工具上使用, 真机不可用</p></div><table tabindex="0"><thead><tr><th>标识符</th><th>属性类型</th><th>描述</th></tr></thead><tbody><tr><td>_id</td><td><a href="#int"><code>int</code></a></td><td></td></tr><tr><td>_pid</td><td><code>int</code></td><td></td></tr><tr><td>id</td><td><a href="#string"><code>string</code></a></td><td></td></tr><tr><td>vid</td><td><code>string</code></td><td></td></tr><tr><td>name</td><td><code>string</code></td><td></td></tr><tr><td>text</td><td><code>string</code></td><td></td></tr><tr><td>desc</td><td><code>string</code></td><td></td></tr><tr><td>clickable</td><td><code>boolean</code></td><td></td></tr><tr><td>focusable</td><td><code>boolean</code></td><td></td></tr><tr><td>checkable</td><td><code>boolean</code></td><td></td></tr><tr><td>checked</td><td><code>boolean</code></td><td></td></tr><tr><td>editable</td><td><code>boolean</code></td><td></td></tr><tr><td>longClickable</td><td><code>boolean</code></td><td></td></tr><tr><td>visibleToUser</td><td><code>boolean</code></td><td></td></tr><tr><td>left</td><td><code>int</code></td><td></td></tr><tr><td>top</td><td><code>int</code></td><td></td></tr><tr><td>right</td><td><code>int</code></td><td></td></tr><tr><td>bottom</td><td><code>int</code></td><td></td></tr><tr><td>width</td><td><code>int</code></td><td></td></tr><tr><td>height</td><td><code>int</code></td><td></td></tr><tr><td>childCount</td><td><code>int</code></td><td></td></tr><tr><td>index</td><td><code>int</code></td><td></td></tr><tr><td>depth</td><td><code>int</code></td><td></td></tr><tr><td>parent</td><td><a href="#node"><code>node</code></a></td><td>获取父节点</td></tr></tbody></table><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>getChild</td><td><code>int</code></td><td><a href="#node"><code>node</code></a></td><td>获取指定索引的子节点</td></tr></tbody></table><h2 id="context" tabindex="-1">context <a class="header-anchor" href="#context" aria-label="Permalink to “context”">​</a></h2><p>context 具有 <a href="#node">node</a> 的所有属性方法, 下面只介绍额外属性方法</p><table tabindex="0"><thead><tr><th>标识符</th><th>属性类型</th><th>描述</th></tr></thead><tbody><tr><td>prev</td><td><a href="#context"><code>context</code></a></td><td>右侧属性选择器的节点上下文 <br> 最右侧的 prev=null</td></tr><tr><td>current</td><td><a href="#node"><code>node</code></a></td><td>当前节点 <br> current.id=id</td></tr></tbody></table><p>示例</p><div class="language-text"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span>FrameLayout[prev.name$=&#39;ImageView&#39;] &gt; ImageView[current.name=name]</span></span></code></pre></div><p>中的 prev 就是 FrameLayout 右侧的 ImageView, current 就是 ImageView</p><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>getPrev</td><td>int</td><td><a href="#context"><code>context</code></a></td><td>快捷获取深层 prev <br> getPrev(0) -&gt; prev <br> getPrev(1) -&gt; prev.prev <br> getPrev(2) -&gt; prev.prev.prev</td></tr></tbody></table><h2 id="global" tabindex="-1">global <a class="header-anchor" href="#global" aria-label="Permalink to “global”">​</a></h2><p>global 具有 <a href="#context">context</a> 的所有属性方法, 并且没有任何属性方法能获取 global 的引用, 下面只介绍额外属性方法</p><table tabindex="0"><thead><tr><th>方法名</th><th>参数</th><th>返回类型</th><th>描述</th></tr></thead><tbody><tr><td>equal</td><td><code>T</code>, <code>T</code></td><td><a href="#boolean"><code>boolean</code></a></td><td>a==b <br> T 是任意类型, a,b 允许 null</td></tr><tr><td>notEqual</td><td><code>T</code>, <code>T</code></td><td><code>boolean</code></td><td>a!=b</td></tr></tbody></table><p>示例</p><div class="language-text"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span>[name=&#39;&#39;][prev.name=&#39;&#39;][current.name=&#39;&#39;][parent.name=&#39;&#39;]</span></span></code></pre></div><ul><li>第一个 <code>name</code> 来自 <a href="#global">global</a>, 实际上任何 <code>xxx</code>/<code>xxx()</code> 都来自 global</li><li>第二个 <code>prev.name</code> 来自 <a href="#context">context</a></li><li>后续的 <code>current.name</code>/<code>parent.name</code> 都来自 <a href="#node">node</a></li></ul>',31)]))}const p=d(r,[["render",c]]);export{g as __pageData,p as default};
@@ -1 +1 @@
1
- import{_ as d,c as e,o,aq as a}from"./chunks/framework.C9O3MI31.js";const g=JSON.parse('{"title":"属性方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/node.md","filePath":"guide/node.md","lastUpdated":1773041507000}'),r={name:"guide/node.md"};function c(n,t,i,l,h,b){return o(),e("div",null,t[0]||(t[0]=[a("",31)]))}const p=d(r,[["render",c]]);export{g as __pageData,p as default};
1
+ import{_ as d,c as e,o,aq as a}from"./chunks/framework.C9O3MI31.js";const g=JSON.parse('{"title":"属性方法","description":"","frontmatter":{},"headers":[],"relativePath":"guide/node.md","filePath":"guide/node.md","lastUpdated":1775561871000}'),r={name:"guide/node.md"};function c(n,t,i,l,h,b){return o(),e("div",null,t[0]||(t[0]=[a("",31)]))}const p=d(r,[["render",c]]);export{g as __pageData,p as default};
@@ -1 +1 @@
1
- import{_ as d,c as o,o as c,aq as i}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"查询优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/optimize.md","filePath":"guide/optimize.md","lastUpdated":1773041507000}'),t={name:"guide/optimize.md"};function l(a,e,n,r,p,u){return c(),o("div",null,e[0]||(e[0]=[i('<h1 id="title" tabindex="-1">查询优化 <a class="header-anchor" href="#title" aria-label="Permalink to “查询优化”">​</a></h1><p>一些关于查询优化的说明</p><h2 id="query-root" tabindex="-1">查找根节点 <a class="header-anchor" href="#query-root" aria-label="Permalink to “查找根节点”">​</a></h2><p>选择器通过满足下列格式的属性选择器标识根节点</p><ul><li><code>[parent=null]</code></li><li><code>A[id=&#39;xxx&#39;][parent=null][text=&#39;xxx&#39;]</code></li></ul><p>即只需存在一个 <code>[parent=null]</code> 就满足条件, 以下是对此的优化</p><h3 id="enforce" tabindex="-1">主动查询 <a class="header-anchor" href="#enforce" aria-label="Permalink to “主动查询”">​</a></h3><p>一般的选择器如 <code>LinearLayout &gt; TextView</code>, 选择器需要从 根节点/事件节点 使用深度先序顺序遍历子孙节点并判断是否满足条件</p><p>如果屏幕上有 n 个节点, 判断逻辑需要运行 n 次</p><p>但是如果选择器是类似 <code>TextView &lt;3 LinearLayout &lt;2 [parent=null]</code>, 由于在右侧标明了从根节点查找</p><p>因此上面的 <code>深度先序顺序遍历子孙节点</code> 将省略, 只进行一次判断, 不需要判断 n 次</p><p>但是如果你在子查询里使用 <code>&lt;&lt;n</code>, 例如 <code>TextView &lt;&lt;n [parent=null]</code></p><p>根据上面说明的优化, 虽然也只有一次判断, 但是由于 <code>&lt;&lt;n</code> 导致内部的子判断也是 n 次, 实际上没有优化判断次数</p><div class="tip custom-block github-alert"><p class="custom-block-title">提示</p><p>实际上从根节点开始匹配并且目标不是根节点的选择器如 <code>A &gt; B</code> 都可等价为 <code>A &gt; @B &lt;&lt;n [parent=null]</code></p></div><h3 id="ancestor" tabindex="-1">祖先节点 <a class="header-anchor" href="#ancestor" aria-label="Permalink to “祖先节点”">​</a></h3><p>在示例 <code>A &lt;3 [parent=null] &gt;n TextView</code> 中, 选择器找到 <code>TextView</code> 后, 根据 <code>&gt;n</code> 表示任意祖先节点</p><p>在默认情况下, 如果 <code>TextView</code> 的层级很深, 那必然需要多次调用 获取父节点 才能最终匹配</p><p>但是如果左侧的选择器是 <code>[parent=null] &gt;n</code>, 这表示找到根节点, 选择器此时不会去执行多次调用 获取父节点</p><p>在 GKD 内部, 根节点可以直接通过 API 获取, 因此 <code>[parent=null] &gt;n</code> 只需要调用一次方法</p><h2 id="fast-query" tabindex="-1">快速查询 <a class="header-anchor" href="#fast-query" aria-label="Permalink to “快速查询”">​</a></h2><div class="note custom-block github-alert"><p class="custom-block-title">注意</p><p>此优化需要设置 <a href="/api/interfaces/RawCommonProps#fastquery">fastQuery</a> 来启用<br> 并且节点在快照面板被标识 <code>可快速查找</code>, 否则查找不到</p></div><h3 id="query-scene" tabindex="-1">查询场景 <a class="header-anchor" href="#query-scene" aria-label="Permalink to “查询场景”">​</a></h3><p>一般情况下, 选择器 <code>[vid=&quot;name&quot;]</code> 需要从 根节点/事件节点 使用深度先序顺序遍历子孙节点并判断是否满足条件</p><p>但是 Android 提供了如下两个快速获取节点的 Api</p><ul><li><a href="https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityNodeInfo#findAccessibilityNodeInfosByViewId(java.lang.String)" target="_blank" rel="noreferrer">findAccessibilityNodeInfosByViewId</a></li><li><a href="https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityNodeInfo#findAccessibilityNodeInfosByText(java.lang.String)" target="_blank" rel="noreferrer">findAccessibilityNodeInfosByText</a></li></ul><p>这使得可以通过 <code>id</code>/<code>vid</code>/<code>text</code> 直接获取子孙节点</p><p>对此我们需要规定符合特定条件的选择器来调用这些 Api 从而跳过手动遍历子孙节点</p><h3 id="rule-format" tabindex="-1">规定格式 <a class="header-anchor" href="#rule-format" aria-label="Permalink to “规定格式”">​</a></h3><p>所有 <code>末尾属性选择器</code>的<code>第一个属性选择表达式</code>符合下面的结构之一</p><ul><li><code>[id=&#39;abc&#39;]</code></li><li><code>[vid=&#39;abc&#39;]</code></li><li><code>[text=&#39;abc&#39;]</code></li><li><code>[text^=&#39;abc&#39;]</code></li><li><code>[text*=&#39;abc&#39;]</code></li><li><code>[text$=&#39;abc&#39;]</code></li></ul><p>或者使用 <code>||</code> 将它们连接形成的逻辑表达式也符合条件, 即如下格式</p><ul><li><code>[id=&#39;abc&#39; || id=&#39;abc2&#39;]</code></li><li><code>[id=&#39;abc&#39; || vid=&#39;abc&#39; || text=&#39;abc&#39; || text^=&#39;abc&#39; || text*=&#39;abc&#39; || text$=&#39;abc&#39;]</code></li></ul><p>这些规定的格式都是为了提取 <code>id</code>/<code>vid</code>/<code>text</code> 来调用上面的两个 Android Api</p><p>下面给出实际示例: ✅ 表示符合格式, ❎ 表示不符合格式</p><ul><li><code>A &gt; B + C[id=&#39;x&#39;][childCount=2]</code> ✅</li><li><code>A &gt; B + C[childCount=2][id=&#39;x&#39;]</code> ❎</li><li><code>A &gt; B + C[id=&#39;x&#39; || text=&#39;manbaout&#39; || text*=&#39;ikun&#39;][childCount=2]</code> ✅</li><li><code>A &gt; B + C[childCount=2][id=&#39;x&#39; || text=&#39;manbaout&#39; || text*=&#39;ikun&#39;]</code> ❎</li></ul><p>这样一个选择器只能在右侧使用快速查询, 为了在中间的子选择器也能使用</p><p>额外规定如果属性选择器如果符合上面格式并且右侧是 <code>&lt;&lt;n</code>, 也能在局部使用快速查找</p><p>示例 <code>A &gt; B + C[id=&#39;x&#39;][childCount=2] &lt;&lt;n D</code> 中的 <code>C[id=&#39;x&#39;][childCount=2] &lt;&lt;n</code> 可以使用局部快速查找</p><p>下面给出满足局部查询优化的示例: ✅ 表示符合格式, ❎ 表示不符合格式</p><ul><li><code>A &gt; B + C[id=&#39;x&#39;][childCount=2] &lt;&lt;n D</code> ✅</li><li><code>A &gt; B + C[childCount=2][id=&#39;x&#39;] &lt;&lt;n D</code> ❎</li></ul><p>上面介绍的是只有一个局部选择器的情况, 下面给出多个局部快速查找的的示例</p><p>如 <code>A &gt; C[id=&#39;x&#39;] &lt;&lt;n D[id=&#39;y&#39;] &lt;&lt;n E</code>, 其中的 <code>C[id=&#39;x&#39;] &lt;&lt;n</code> 和 <code>D[id=&#39;y&#39;] &lt;&lt;n</code> 都可以使用局部快速查找</p><p>如果使用 <code>||</code>, <code>&amp;&amp;</code> 连接多个选择器时, 快速查询为它们的并集</p><p>如果选择器被 <code>!(xxx)</code> 包裹, 则不符合快速查询格式, 也就是 <code>!</code> 会取消其内部所有的快速查询</p><ul><li><code>(A + B[id=&#39;b&#39;]) || (C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code>, <code>id=&#39;d&#39;</code></li><li><code>(A + B[id=&#39;b&#39;]) &amp;&amp; (C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code>, <code>id=&#39;d&#39;</code></li><li><code>(A + B[id=&#39;b&#39;]) &amp;&amp; !(C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code></li></ul><p>需要注意的是它们内部的 局部快速查找 仍然独立成立</p><ul><li><code>(X[id=&#39;x&#39;] &lt;&lt;n A + B[id=&#39;b&#39;]) &amp;&amp; !(Y[id=&#39;y&#39;] &lt;&lt;n C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code>, 局部快速查询分别是 <code>id=&#39;x&#39;</code>, <code>id=&#39;y&#39;</code></li></ul><div class="note custom-block github-alert"><p class="custom-block-title">注意</p><p>如果选择器不存在满足快速查找的格式, fastQuery 是否开启都不影响查询复杂度</p></div><h3 id="optimize-example" tabindex="-1">优化示例 <a class="header-anchor" href="#optimize-example" aria-label="Permalink to “优化示例”">​</a></h3><p>以 <a href="https://i.gkd.li/i/16201605?gkd=W3ZpZD0iaW1hZ2UiXSA8PG4gW3ZpZD0icmVjeWNsZXJWaWV3Il0gPDxuIFt2aWQ9ImNvbnRlbnRfbGF5b3V0Il0" target="_blank" rel="noreferrer"><code>[vid=&quot;image&quot;] &lt;&lt;n [vid=&quot;recyclerView&quot;] &lt;&lt;n [vid=&quot;content_layout&quot;]</code></a> 为例</p><p>上面的选择器存在 3 个快速查找优化</p><ul><li><code>[vid=&quot;content_layout&quot;]</code> 从 根节点 优化查询找到 <code>content_layout</code></li><li><code>[vid=&quot;recyclerView&quot;]</code> 从 <code>content_layout</code> 优化查询找到 <code>recyclerView</code></li><li><code>[vid=&quot;image&quot;]</code> 从 <code>recyclerView</code> 优化查询找到 <code>image</code></li></ul><p>也就是只需要调用 <code>findAccessibilityNodeInfosByViewId</code> 3 次即可得到目标节点</p><p>如果是从根节点开始查询, 根据快照内的 选择器路径视图</p><ul><li><code>[vid=&quot;content_layout&quot;]</code> 从 根节点 需要 7 次找到 <code>content_layout</code></li><li><code>[vid=&quot;recyclerView&quot;]</code> 从 <code>content_layout</code> 需要 48 次找到 <code>recyclerView</code></li><li><code>[vid=&quot;image&quot;]</code> 从 <code>recyclerView</code> 需要 44 次找到 <code>image</code></li></ul>',55)]))}const h=d(t,[["render",l]]);export{b as __pageData,h as default};
1
+ import{_ as d,c as o,o as c,aq as i}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"查询优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/optimize.md","filePath":"guide/optimize.md","lastUpdated":1775561871000}'),t={name:"guide/optimize.md"};function l(a,e,n,r,p,u){return c(),o("div",null,e[0]||(e[0]=[i('<h1 id="title" tabindex="-1">查询优化 <a class="header-anchor" href="#title" aria-label="Permalink to “查询优化”">​</a></h1><p>一些关于查询优化的说明</p><h2 id="query-root" tabindex="-1">查找根节点 <a class="header-anchor" href="#query-root" aria-label="Permalink to “查找根节点”">​</a></h2><p>选择器通过满足下列格式的属性选择器标识根节点</p><ul><li><code>[parent=null]</code></li><li><code>A[id=&#39;xxx&#39;][parent=null][text=&#39;xxx&#39;]</code></li></ul><p>即只需存在一个 <code>[parent=null]</code> 就满足条件, 以下是对此的优化</p><h3 id="enforce" tabindex="-1">主动查询 <a class="header-anchor" href="#enforce" aria-label="Permalink to “主动查询”">​</a></h3><p>一般的选择器如 <code>LinearLayout &gt; TextView</code>, 选择器需要从 根节点/事件节点 使用深度先序顺序遍历子孙节点并判断是否满足条件</p><p>如果屏幕上有 n 个节点, 判断逻辑需要运行 n 次</p><p>但是如果选择器是类似 <code>TextView &lt;3 LinearLayout &lt;2 [parent=null]</code>, 由于在右侧标明了从根节点查找</p><p>因此上面的 <code>深度先序顺序遍历子孙节点</code> 将省略, 只进行一次判断, 不需要判断 n 次</p><p>但是如果你在子查询里使用 <code>&lt;&lt;n</code>, 例如 <code>TextView &lt;&lt;n [parent=null]</code></p><p>根据上面说明的优化, 虽然也只有一次判断, 但是由于 <code>&lt;&lt;n</code> 导致内部的子判断也是 n 次, 实际上没有优化判断次数</p><div class="tip custom-block github-alert"><p class="custom-block-title">提示</p><p>实际上从根节点开始匹配并且目标不是根节点的选择器如 <code>A &gt; B</code> 都可等价为 <code>A &gt; @B &lt;&lt;n [parent=null]</code></p></div><h3 id="ancestor" tabindex="-1">祖先节点 <a class="header-anchor" href="#ancestor" aria-label="Permalink to “祖先节点”">​</a></h3><p>在示例 <code>A &lt;3 [parent=null] &gt;n TextView</code> 中, 选择器找到 <code>TextView</code> 后, 根据 <code>&gt;n</code> 表示任意祖先节点</p><p>在默认情况下, 如果 <code>TextView</code> 的层级很深, 那必然需要多次调用 获取父节点 才能最终匹配</p><p>但是如果左侧的选择器是 <code>[parent=null] &gt;n</code>, 这表示找到根节点, 选择器此时不会去执行多次调用 获取父节点</p><p>在 GKD 内部, 根节点可以直接通过 API 获取, 因此 <code>[parent=null] &gt;n</code> 只需要调用一次方法</p><h2 id="fast-query" tabindex="-1">快速查询 <a class="header-anchor" href="#fast-query" aria-label="Permalink to “快速查询”">​</a></h2><div class="note custom-block github-alert"><p class="custom-block-title">注意</p><p>此优化需要设置 <a href="/api/interfaces/RawCommonProps#fastquery">fastQuery</a> 来启用<br> 并且节点在快照面板被标识 <code>可快速查找</code>, 否则查找不到</p></div><h3 id="query-scene" tabindex="-1">查询场景 <a class="header-anchor" href="#query-scene" aria-label="Permalink to “查询场景”">​</a></h3><p>一般情况下, 选择器 <code>[vid=&quot;name&quot;]</code> 需要从 根节点/事件节点 使用深度先序顺序遍历子孙节点并判断是否满足条件</p><p>但是 Android 提供了如下两个快速获取节点的 Api</p><ul><li><a href="https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityNodeInfo#findAccessibilityNodeInfosByViewId(java.lang.String)" target="_blank" rel="noreferrer">findAccessibilityNodeInfosByViewId</a></li><li><a href="https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityNodeInfo#findAccessibilityNodeInfosByText(java.lang.String)" target="_blank" rel="noreferrer">findAccessibilityNodeInfosByText</a></li></ul><p>这使得可以通过 <code>id</code>/<code>vid</code>/<code>text</code> 直接获取子孙节点</p><p>对此我们需要规定符合特定条件的选择器来调用这些 Api 从而跳过手动遍历子孙节点</p><h3 id="rule-format" tabindex="-1">规定格式 <a class="header-anchor" href="#rule-format" aria-label="Permalink to “规定格式”">​</a></h3><p>所有 <code>末尾属性选择器</code>的<code>第一个属性选择表达式</code>符合下面的结构之一</p><ul><li><code>[id=&#39;abc&#39;]</code></li><li><code>[vid=&#39;abc&#39;]</code></li><li><code>[text=&#39;abc&#39;]</code></li><li><code>[text^=&#39;abc&#39;]</code></li><li><code>[text*=&#39;abc&#39;]</code></li><li><code>[text$=&#39;abc&#39;]</code></li></ul><p>或者使用 <code>||</code> 将它们连接形成的逻辑表达式也符合条件, 即如下格式</p><ul><li><code>[id=&#39;abc&#39; || id=&#39;abc2&#39;]</code></li><li><code>[id=&#39;abc&#39; || vid=&#39;abc&#39; || text=&#39;abc&#39; || text^=&#39;abc&#39; || text*=&#39;abc&#39; || text$=&#39;abc&#39;]</code></li></ul><p>这些规定的格式都是为了提取 <code>id</code>/<code>vid</code>/<code>text</code> 来调用上面的两个 Android Api</p><p>下面给出实际示例: ✅ 表示符合格式, ❎ 表示不符合格式</p><ul><li><code>A &gt; B + C[id=&#39;x&#39;][childCount=2]</code> ✅</li><li><code>A &gt; B + C[childCount=2][id=&#39;x&#39;]</code> ❎</li><li><code>A &gt; B + C[id=&#39;x&#39; || text=&#39;manbaout&#39; || text*=&#39;ikun&#39;][childCount=2]</code> ✅</li><li><code>A &gt; B + C[childCount=2][id=&#39;x&#39; || text=&#39;manbaout&#39; || text*=&#39;ikun&#39;]</code> ❎</li></ul><p>这样一个选择器只能在右侧使用快速查询, 为了在中间的子选择器也能使用</p><p>额外规定如果属性选择器如果符合上面格式并且右侧是 <code>&lt;&lt;n</code>, 也能在局部使用快速查找</p><p>示例 <code>A &gt; B + C[id=&#39;x&#39;][childCount=2] &lt;&lt;n D</code> 中的 <code>C[id=&#39;x&#39;][childCount=2] &lt;&lt;n</code> 可以使用局部快速查找</p><p>下面给出满足局部查询优化的示例: ✅ 表示符合格式, ❎ 表示不符合格式</p><ul><li><code>A &gt; B + C[id=&#39;x&#39;][childCount=2] &lt;&lt;n D</code> ✅</li><li><code>A &gt; B + C[childCount=2][id=&#39;x&#39;] &lt;&lt;n D</code> ❎</li></ul><p>上面介绍的是只有一个局部选择器的情况, 下面给出多个局部快速查找的的示例</p><p>如 <code>A &gt; C[id=&#39;x&#39;] &lt;&lt;n D[id=&#39;y&#39;] &lt;&lt;n E</code>, 其中的 <code>C[id=&#39;x&#39;] &lt;&lt;n</code> 和 <code>D[id=&#39;y&#39;] &lt;&lt;n</code> 都可以使用局部快速查找</p><p>如果使用 <code>||</code>, <code>&amp;&amp;</code> 连接多个选择器时, 快速查询为它们的并集</p><p>如果选择器被 <code>!(xxx)</code> 包裹, 则不符合快速查询格式, 也就是 <code>!</code> 会取消其内部所有的快速查询</p><ul><li><code>(A + B[id=&#39;b&#39;]) || (C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code>, <code>id=&#39;d&#39;</code></li><li><code>(A + B[id=&#39;b&#39;]) &amp;&amp; (C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code>, <code>id=&#39;d&#39;</code></li><li><code>(A + B[id=&#39;b&#39;]) &amp;&amp; !(C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code></li></ul><p>需要注意的是它们内部的 局部快速查找 仍然独立成立</p><ul><li><code>(X[id=&#39;x&#39;] &lt;&lt;n A + B[id=&#39;b&#39;]) &amp;&amp; !(Y[id=&#39;y&#39;] &lt;&lt;n C + D[id=&#39;d&#39;])</code> 的快速查询为 <code>id=&#39;b&#39;</code>, 局部快速查询分别是 <code>id=&#39;x&#39;</code>, <code>id=&#39;y&#39;</code></li></ul><div class="note custom-block github-alert"><p class="custom-block-title">注意</p><p>如果选择器不存在满足快速查找的格式, fastQuery 是否开启都不影响查询复杂度</p></div><h3 id="optimize-example" tabindex="-1">优化示例 <a class="header-anchor" href="#optimize-example" aria-label="Permalink to “优化示例”">​</a></h3><p>以 <a href="https://i.gkd.li/i/16201605?gkd=W3ZpZD0iaW1hZ2UiXSA8PG4gW3ZpZD0icmVjeWNsZXJWaWV3Il0gPDxuIFt2aWQ9ImNvbnRlbnRfbGF5b3V0Il0" target="_blank" rel="noreferrer"><code>[vid=&quot;image&quot;] &lt;&lt;n [vid=&quot;recyclerView&quot;] &lt;&lt;n [vid=&quot;content_layout&quot;]</code></a> 为例</p><p>上面的选择器存在 3 个快速查找优化</p><ul><li><code>[vid=&quot;content_layout&quot;]</code> 从 根节点 优化查询找到 <code>content_layout</code></li><li><code>[vid=&quot;recyclerView&quot;]</code> 从 <code>content_layout</code> 优化查询找到 <code>recyclerView</code></li><li><code>[vid=&quot;image&quot;]</code> 从 <code>recyclerView</code> 优化查询找到 <code>image</code></li></ul><p>也就是只需要调用 <code>findAccessibilityNodeInfosByViewId</code> 3 次即可得到目标节点</p><p>如果是从根节点开始查询, 根据快照内的 选择器路径视图</p><ul><li><code>[vid=&quot;content_layout&quot;]</code> 从 根节点 需要 7 次找到 <code>content_layout</code></li><li><code>[vid=&quot;recyclerView&quot;]</code> 从 <code>content_layout</code> 需要 48 次找到 <code>recyclerView</code></li><li><code>[vid=&quot;image&quot;]</code> 从 <code>recyclerView</code> 需要 44 次找到 <code>image</code></li></ul>',55)]))}const h=d(t,[["render",l]]);export{b as __pageData,h as default};
@@ -1 +1 @@
1
- import{_ as d,c as o,o as c,aq as i}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"查询优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/optimize.md","filePath":"guide/optimize.md","lastUpdated":1773041507000}'),t={name:"guide/optimize.md"};function l(a,e,n,r,p,u){return c(),o("div",null,e[0]||(e[0]=[i("",55)]))}const h=d(t,[["render",l]]);export{b as __pageData,h as default};
1
+ import{_ as d,c as o,o as c,aq as i}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"查询优化","description":"","frontmatter":{},"headers":[],"relativePath":"guide/optimize.md","filePath":"guide/optimize.md","lastUpdated":1775561871000}'),t={name:"guide/optimize.md"};function l(a,e,n,r,p,u){return c(),o("div",null,e[0]||(e[0]=[i("",55)]))}const h=d(t,[["render",l]]);export{b as __pageData,h as default};
@@ -1 +1 @@
1
- import{_ as d,c as a,o as r,aq as e}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"隐私政策","description":"","frontmatter":{},"headers":[],"relativePath":"guide/privacy.md","filePath":"guide/privacy.md","lastUpdated":1773041507000}'),i={name:"guide/privacy.md"};function l(h,t,n,o,p,s){return r(),a("div",null,t[0]||(t[0]=[e('<h1 id="title" tabindex="-1">隐私政策 <a class="header-anchor" href="#title" aria-label="Permalink to “隐私政策”">​</a></h1><p><strong>版本号:1.0</strong><br><strong>生效日期:以应用版本发布日期为准</strong></p><p>本隐私政策旨在说明我们如何处理您的数据。</p><p>GKD 应用秉持 “本地优先、最小权限、完全离线” 原则。</p><p><strong>我们不会收集、存储或上传任何用户隐私数据</strong>。</p><h2 id="p1" tabindex="-1">一、我们如何处理您的数据 <a class="header-anchor" href="#p1" aria-label="Permalink to “一、我们如何处理您的数据”">​</a></h2><table tabindex="0"><thead><tr><th>数据类型</th><th>使用目的</th><th>是否上传</th><th>存储位置</th></tr></thead><tbody><tr><td>本地规则与配置</td><td>用户自定义自动化行为</td><td>否</td><td>本地</td></tr><tr><td>屏幕截图(仅调试)</td><td>用户调试辅助功能</td><td>否</td><td>本地</td></tr><tr><td>屏幕文本信息</td><td>文本识别以实现查询功能</td><td>否</td><td>本地</td></tr><tr><td>本地日志</td><td>保存运行或报错信息供调试</td><td>否</td><td>本地</td></tr><tr><td>数据导出(配置/规则)</td><td>用户自行备份与迁移</td><td>否</td><td>本地或自行分享</td></tr></tbody></table><h2 id="p2" tabindex="-1">二、权限使用说明 <a class="header-anchor" href="#p2" aria-label="Permalink to “二、权限使用说明”">​</a></h2><table tabindex="0"><thead><tr><th>权限</th><th>是否必须</th><th>用途说明</th></tr></thead><tbody><tr><td>无障碍服务</td><td>❌ 否</td><td>用于模拟点击和界面读取(选用功能)</td></tr><tr><td>屏幕截图权限</td><td>❌ 否</td><td>调试界面内容(选用功能)</td></tr><tr><td>网络权限</td><td>❌ 否</td><td>检测更新或导入订阅或网络调试(选用功能)</td></tr><tr><td>外部存储写权限</td><td>❌ 否</td><td>部分旧设备导出文件时使用(选用功能)</td></tr></tbody></table><h2 id="p3" tabindex="-1">三、数据导入与导出说明 <a class="header-anchor" href="#p3" aria-label="Permalink to “三、数据导入与导出说明”">​</a></h2><ul><li>所有规则、配置、日志等数据仅保存在用户本地;</li><li>用户可通过系统分享功能导出文件,无需申请权限;</li><li>部分旧设备或旧系统中,普通版导出文件可能会申请写入下载目录权限,且用途仅限导出功能。</li></ul><h2 id="p4" tabindex="-1">四、第三方库说明 <a class="header-anchor" href="#p4" aria-label="Permalink to “四、第三方库说明”">​</a></h2><p>本应用所使用的第三方库均为开源项目,不包含任何用户跟踪、统计或联网行为。完整依赖列表可在项目开源仓库中查看。</p><h2 id="p5" tabindex="-1">五、用户权利 <a class="header-anchor" href="#p5" aria-label="Permalink to “五、用户权利”">​</a></h2><p>您有权:</p><ul><li>拒绝授予任何权限</li><li>随时导出、编辑或删除本地数据</li><li>卸载应用以终止使用</li></ul><h2 id="p6" tabindex="-1">六、隐私政策变更 <a class="header-anchor" href="#p6" aria-label="Permalink to “六、隐私政策变更”">​</a></h2><p>如隐私政策有更新,将随应用更新发布。您可在官网或应用内查阅最新版,继续使用即视为接受变更。</p>',18)]))}const _=d(i,[["render",l]]);export{b as __pageData,_ as default};
1
+ import{_ as d,c as a,o as r,aq as e}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"隐私政策","description":"","frontmatter":{},"headers":[],"relativePath":"guide/privacy.md","filePath":"guide/privacy.md","lastUpdated":1775561871000}'),i={name:"guide/privacy.md"};function l(h,t,n,o,p,s){return r(),a("div",null,t[0]||(t[0]=[e('<h1 id="title" tabindex="-1">隐私政策 <a class="header-anchor" href="#title" aria-label="Permalink to “隐私政策”">​</a></h1><p><strong>版本号:1.0</strong><br><strong>生效日期:以应用版本发布日期为准</strong></p><p>本隐私政策旨在说明我们如何处理您的数据。</p><p>GKD 应用秉持 “本地优先、最小权限、完全离线” 原则。</p><p><strong>我们不会收集、存储或上传任何用户隐私数据</strong>。</p><h2 id="p1" tabindex="-1">一、我们如何处理您的数据 <a class="header-anchor" href="#p1" aria-label="Permalink to “一、我们如何处理您的数据”">​</a></h2><table tabindex="0"><thead><tr><th>数据类型</th><th>使用目的</th><th>是否上传</th><th>存储位置</th></tr></thead><tbody><tr><td>本地规则与配置</td><td>用户自定义自动化行为</td><td>否</td><td>本地</td></tr><tr><td>屏幕截图(仅调试)</td><td>用户调试辅助功能</td><td>否</td><td>本地</td></tr><tr><td>屏幕文本信息</td><td>文本识别以实现查询功能</td><td>否</td><td>本地</td></tr><tr><td>本地日志</td><td>保存运行或报错信息供调试</td><td>否</td><td>本地</td></tr><tr><td>数据导出(配置/规则)</td><td>用户自行备份与迁移</td><td>否</td><td>本地或自行分享</td></tr></tbody></table><h2 id="p2" tabindex="-1">二、权限使用说明 <a class="header-anchor" href="#p2" aria-label="Permalink to “二、权限使用说明”">​</a></h2><table tabindex="0"><thead><tr><th>权限</th><th>是否必须</th><th>用途说明</th></tr></thead><tbody><tr><td>无障碍服务</td><td>❌ 否</td><td>用于模拟点击和界面读取(选用功能)</td></tr><tr><td>屏幕截图权限</td><td>❌ 否</td><td>调试界面内容(选用功能)</td></tr><tr><td>网络权限</td><td>❌ 否</td><td>检测更新或导入订阅或网络调试(选用功能)</td></tr><tr><td>外部存储写权限</td><td>❌ 否</td><td>部分旧设备导出文件时使用(选用功能)</td></tr></tbody></table><h2 id="p3" tabindex="-1">三、数据导入与导出说明 <a class="header-anchor" href="#p3" aria-label="Permalink to “三、数据导入与导出说明”">​</a></h2><ul><li>所有规则、配置、日志等数据仅保存在用户本地;</li><li>用户可通过系统分享功能导出文件,无需申请权限;</li><li>部分旧设备或旧系统中,普通版导出文件可能会申请写入下载目录权限,且用途仅限导出功能。</li></ul><h2 id="p4" tabindex="-1">四、第三方库说明 <a class="header-anchor" href="#p4" aria-label="Permalink to “四、第三方库说明”">​</a></h2><p>本应用所使用的第三方库均为开源项目,不包含任何用户跟踪、统计或联网行为。完整依赖列表可在项目开源仓库中查看。</p><h2 id="p5" tabindex="-1">五、用户权利 <a class="header-anchor" href="#p5" aria-label="Permalink to “五、用户权利”">​</a></h2><p>您有权:</p><ul><li>拒绝授予任何权限</li><li>随时导出、编辑或删除本地数据</li><li>卸载应用以终止使用</li></ul><h2 id="p6" tabindex="-1">六、隐私政策变更 <a class="header-anchor" href="#p6" aria-label="Permalink to “六、隐私政策变更”">​</a></h2><p>如隐私政策有更新,将随应用更新发布。您可在官网或应用内查阅最新版,继续使用即视为接受变更。</p>',18)]))}const _=d(i,[["render",l]]);export{b as __pageData,_ as default};
@@ -1 +1 @@
1
- import{_ as d,c as a,o as r,aq as e}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"隐私政策","description":"","frontmatter":{},"headers":[],"relativePath":"guide/privacy.md","filePath":"guide/privacy.md","lastUpdated":1773041507000}'),i={name:"guide/privacy.md"};function l(h,t,n,o,p,s){return r(),a("div",null,t[0]||(t[0]=[e("",18)]))}const _=d(i,[["render",l]]);export{b as __pageData,_ as default};
1
+ import{_ as d,c as a,o as r,aq as e}from"./chunks/framework.C9O3MI31.js";const b=JSON.parse('{"title":"隐私政策","description":"","frontmatter":{},"headers":[],"relativePath":"guide/privacy.md","filePath":"guide/privacy.md","lastUpdated":1775561871000}'),i={name:"guide/privacy.md"};function l(h,t,n,o,p,s){return r(),a("div",null,t[0]||(t[0]=[e("",18)]))}const _=d(i,[["render",l]]);export{b as __pageData,_ as default};