快速退出当前应用 [No Root]

前言

一直以来,我都是使用Tasker 和 AutoInput 实现快速退出当前应用的功能,不过接触 Autojs 后,发现它处理界面元素的能力远远高于 AutoInput,因此便将这一功能改由 Autojs 来实现,下面是本人编写的快速退出当前应用的脚本,供有需要的人参考或使用。

效果

快速退出当前应用的动态图

原理

参见:使用Tasker 和 AutoInput 快速退出当前应用

脚本实现

各脚本文件的目录结构。(存放 Autojs 脚本的文件夹名在英语环境下为 Scripts,在中文环境下为 脚本

└─Scripts(脚本)
    ├─comm
    │      exit-app-action.js
    │      exit-app.js
    │      
    └─utils
            ui.js

注:若自行更改了脚本文件的存放路径,则记得更新脚本中与其相关的加载模块路径。

  • UI工具模块

    // ui.js
    
    module.exports = (() => {
      const ROOT_NODE_NAME = 'FrameLayout';
      const TIMEOUT_FOR_LOOKUP_NODE = 250;
    
      // 获取当前应用的包名
      const getCurrentPackage = function getPackageNameOfTheForegroundApplication(timeout) {
        const node = getRootNode(timeout);
        return node !== null ? node.packageName() : currentPackage();
      };
    
      // 获取 FrameLayout 根节点
      const getRootNode = function getFrameLayoutNode(timeout) {
        return className(ROOT_NODE_NAME).findOne(timeout || TIMEOUT_FOR_LOOKUP_NODE);
      };
    
      // 获取所有指定节点及其子节点的描述内容和文本内容
      const getAllTextualContent = function getAllDescriptionAndTextUnderNodeRecursively(node) {
        let items = [];
        const getDescAndText = function(node) {
          if (node !== null) {
            items.push(node.desc());
            items.push(node.text());
    
            for (let len = node.childCount(), i = 0; i < len; i++) {
              getDescAndText(node.child(i));
            }
          }
        };
    
        getDescAndText(node || getRootNode());
        return items.filter(item => item !== '' && item !== null);
      };
    
      return {
        getCurrentPackage: getCurrentPackage,
        getAllTextualContent: getAllTextualContent,
      };
    })();
    
  • 退出当前应用的模块 exit-app-action.js

    // exit-app-action.js
    
    module.exports = (() => {
      const uiUtils = require('../utils/ui');
    
      // 通过模拟(多次)点击返回键退出当前应用,并显示当前应用的退出结果
      const exitApp = function exitForegroundApplicationUsingReturnKey() {
        showResult(returnUntilExitingApp());
      };
    
      // 显示当前应用的退出结果
      const showResult = function showExitForegroundApplicationResult(result) {
        const state = result.success ? 'has exited' : 'cannot exit';
        const message = getAppName(result.package) + ' ' + state;
        toast(message);
      };
    
      // 一直按下返回键,直至当前应用退出为止
      const returnUntilExitingApp = function keepReturningUntilExitingForegroundApplication() {
        const TIME_REQUIRED_FOR_RETURN = 100;
        const MAXIMUM_RETURN_IN_SAME_UI = 10;
        let prevPackage = uiUtils.getCurrentPackage();
        let result = { package: prevPackage, success: false };
        let sameui = getSameUiInfo();
    
        while (true) {
          back();
          sleep(TIME_REQUIRED_FOR_RETURN);
    
          if (uiUtils.getCurrentPackage() !== prevPackage) {
            result.success = true;
            break;
          }
    
          if (sameui.number + 1 >= MAXIMUM_RETURN_IN_SAME_UI) break;
    
          sameui.updateNum();
        }
    
        return result;
      };
    
      // 获取相同界面的次数
      const getSameUiInfo = function getInfoAboutNumberOfTimesOfTheSameUi() {
        return {
          number: 1,
          prevText: null,
          updateNum: function() {
            let curText = uiUtils.getAllTextualContent().toString();
            this.number = curText !== this.prevText ? 1 : this.number + 1;
            this.prevText = curText;
          },
        };
      };
    
      return {
        exitApp: exitApp,
        returnUntilExitingApp: returnUntilExitingApp,
      };
    })();
    
  • 调用 exit-app-action 模块中的 exitApp 方法

    // exit-app.js
    
    // 执行退出当前应用的动作
    require('./exit-app-action').exitApp();
    

若想使用无注释脚本,可通过访问这里获取。

使用方法

可借助 TaskerXposed edge pro 调用脚本文件 exit-app.js,然后使用一些手势应用来执行。

更新日志

  • 6/30/2018
    - 发布

其他

作者:sung
邮箱:sdfsung@gmail.com

原创内容,转载请注明出处

。我小米手机,直接长按下面的返回键

你这变量名起的让我头皮发麻,能不能稍微缩写一下,用起来不难受吗。。。

管理员

@thehot 这种变量名,符合开发人员的一般习惯, 都改成 a b c d e f g 的变量名,你能懂?

  • 4
    帖子
  • 783
    浏览

与 Auto.js 的连接断开,我们正在尝试重连,请耐心等待