App 应用操作¶
App 模块提供了应用相关的操作功能,包括获取应用信息、打开 URL、管理日志、查看崩溃报告,以及使用私有 API 管理其他应用。
守护进程支持: 部分支持。
open、launch、openSettings在 Daemon 模式下不可用,vibrate在后台可能不生效。
目录¶
快速开始¶
// 获取应用信息
const info = app.info();
console.log(`${info.name} v${info.version}`);
// 打开 URL
app.open('https://example.com');
// 获取日志
const logs = app.getLogs(50);
console.log(`最近 ${logs.length} 条日志`);
// 列出所有应用(私有 API)
const apps = app.list();
console.log(`已安装 ${apps.length} 个应用`);
API 参考¶
应用信息¶
app.version()¶
获取应用版本号。返回: string
app.build()¶
获取构建号。返回: string
app.bundleId()¶
获取 Bundle ID。返回: string
app.info()¶
获取完整应用信息。返回: object - 包含 name, version, build, bundleId, language
const info = app.info();
console.log(info);
// { name: "TrollScript", version: "1.0.0", build: "1", bundleId: "com.example.app", language: "zh" }
URL 操作¶
app.open(url)¶
打开 URL 或 URL Scheme。参数: url (string) 返回: boolean (Daemon 模式下不可用)
app.open('https://example.com');
app.open('shortcuts://run-shortcut?name=MyShortcut');
app.canOpen(url)¶
检查是否能打开指定 URL。参数: url (string) 返回: boolean
app.openSettings()¶
打开应用设置页面。返回: boolean (Daemon 模式下返回 false)
Daemon 控制¶
app.restartDaemon()¶
重启 TrollScript HUD Daemon 进程。返回: boolean
const ok = app.restartDaemon();
console.log(`重启请求: ${ok ? '已发送' : '失败'}`);
说明: - 这是一个 App 侧能力,用于请求重启 TrollScript 的 HUD/Daemon 进程。 - 该方法会确保
schedulerEnabled = true后再发起重启流程。 - 适合在脚本里做“自恢复”或更新后重启守护进程。
// 示例:重启 Daemon 后等待恢复
function restartDaemonAndWait() {
console.log('准备重启 Daemon...');
const requested = app.restartDaemon();
if (!requested) {
console.error('重启请求发送失败');
return false;
}
console.log('重启请求已发送,等待守护进程恢复...');
// 简单等待 watchdog / daemon 拉起
setTimeout(() => {
console.log('Daemon 应该已经开始恢复,可继续后续逻辑');
}, 2000);
return true;
}
restartDaemonAndWait();
用户交互¶
app.vibrate()¶
触发设备震动反馈。返回: void (Daemon 模式下可能不生效)
// 触发震动
app.vibrate();
日志管理¶
app.getLogs(limit?)¶
获取应用日志。参数: limit (number, 默认 100) 返回: array
const logs = app.getLogs(50);
logs.forEach(log => {
console.log(`[${log.level}] ${log.message}`);
});
app.exportLogs()¶
导出所有日志为字符串。返回: string
app.clearLogs()¶
清除所有日志。返回: void
app.exit(code?)¶
退出应用(仅用于调试)。参数: code (number, 可选, 默认 0) - 退出码 返回: void
// 正常退出
app.exit();
// 以错误码退出
app.exit(1);
⚠️ 警告: 此方法会立即终止应用,仅用于调试目的。
崩溃报告¶
app.getCrashReports()¶
获取所有崩溃报告。返回: array
const crashes = app.getCrashReports();
crashes.forEach(crash => {
console.log(`崩溃时间: ${new Date(crash.date * 1000)}`);
console.log(`原因: ${crash.reason}`);
});
app.getLastCrash()¶
获取最近一次崩溃报告。返回: object | null
性能监控¶
app.cpuUsage()¶
获取 CPU 使用率(进程级 + 系统级)。返回: object
const cpu = app.cpuUsage();
console.log(`进程 CPU: ${cpu.process.toFixed(1)}%`);
console.log(`系统 CPU: ${cpu.system.total.toFixed(1)}%`);
console.log(`用户态: ${cpu.system.user.toFixed(1)}%`);
console.log(`系统态: ${cpu.system.system.toFixed(1)}%`);
console.log(`空闲: ${cpu.system.idle.toFixed(1)}%`);
console.log(`CPU 核心数: ${cpu.system.cores}`);
返回对象结构:
{
process: 12.5, // 当前进程 CPU 使用率 (%)
system: {
total: 45.2, // 系统总 CPU 使用率 (%)
user: 30.1, // 用户态 CPU (%)
system: 15.1, // 系统态 CPU (%)
idle: 54.8, // 空闲 CPU (%)
nice: 0.0, // Nice 优先级 CPU (%)
cores: 6 // CPU 核心数
}
}
app.memoryUsage()¶
获取内存使用情况。返回: object
const mem = app.memoryUsage();
console.log(`当前内存: ${mem.usage.toFixed(1)} ${mem.unit}`);
console.log(`峰值内存: ${mem.peak.toFixed(1)} ${mem.unit}`);
返回对象结构:
{
usage: 156.8, // 当前内存使用量
peak: 189.2, // 峰值内存使用量
unit: "MB" // 单位
}
app.fps()¶
获取当前帧率。返回: object
const fpsInfo = app.fps();
console.log(`FPS: ${Math.round(fpsInfo.fps)}`);
if (fpsInfo.isCritical) {
console.warn('帧率过低!');
}
返回对象结构:
{
fps: 60.0, // 当前帧率
isWarning: false, // 是否处于警告状态 (内存>200MB 或 CPU>80% 或 FPS<30)
isCritical: false // 是否处于危险状态 (内存>400MB 或 CPU>95% 或 FPS<15)
}
app.performanceSnapshot()¶
获取完整性能指标快照。返回: object
const snapshot = app.performanceSnapshot();
console.log(JSON.stringify(snapshot, null, 2));
返回完整的性能数据,包含 CPU、内存、FPS 和时间戳。
app.startMonitoring()¶
开启性能监控(FPS 采样、指标记录)。返回: boolean
app.startMonitoring();
// 监控中...
setTimeout(() => {
const fps = app.fps();
console.log(`当前 FPS: ${fps.fps}`);
}, 2000);
注意: 开启监控后才能获取准确的 FPS 数据。
app.stopMonitoring()¶
停止性能监控。返回: boolean
app.stopMonitoring();
app.performanceRecords(limit?)¶
获取历史性能记录。参数: limit (number, 默认 50) 返回: array
const records = app.performanceRecords(10);
records.forEach(record => {
console.log(`脚本: ${record.scriptName}`);
console.log(`执行时间: ${record.executionTime.toFixed(2)}ms`);
console.log(`峰值内存: ${record.peakMemory.toFixed(1)}MB`);
console.log(`成功: ${record.success}`);
});
返回数组元素结构:
{
id: "uuid-string",
scriptName: "MyScript",
executionTime: 123.45, // 执行时间 (ms)
peakMemory: 156.8, // 峰值内存 (MB)
averageCPU: 25.3, // 平均 CPU (%)
timestamp: 1704067200.0, // 时间戳
success: true // 是否成功
}
app.clearPerformanceRecords()¶
清除所有性能记录。返回: void
app.clearPerformanceRecords();
应用管理(私有 API)¶
app.list()¶
获取所有已安装应用列表。返回: array
const apps = app.list();
apps.forEach(app => {
console.log(`${app.name} (${app.bundleId})`);
});
app.getAppInfo(bundleId)¶
获取指定应用信息。参数: bundleId (string) 返回: object | null
app.launch(bundleId)¶
启动指定应用。参数: bundleId (string) 返回: boolean (Daemon 模式下不可用)
app.launch('com.apple.mobilesafari');
app.terminate(bundleId)¶
终止指定应用。参数: bundleId (string) 返回: boolean
app.isInstalled(bundleId)¶
检查应用是否已安装。参数: bundleId (string) 返回: boolean
app.getDataContainer(bundleId)¶
获取应用数据容器路径。参数: bundleId (string) 返回: string | null
Darwin Notification¶
Darwin Notification 是 iOS 系统级的通知机制,可用于进程间通信。
app.notifyPost(name)¶
发送 Darwin Notification。参数: name (string) - notification 名称 返回: boolean - 是否发送成功
// 发送通知 唤起 Copylog
const success = app.notifyPost('me.tomt000.copylog.showView');
if (success) {
console.log('通知发送成功');
}
app.notifyRegister(name)¶
注册监听 Darwin Notification。参数: name (string) - notification 名称 返回: number - 监听 token
// 注册监听
const token = app.notifyRegister('com.example.mynotification');
console.log('注册成功,token:', token);
app.notifyCancel(token)¶
取消监听 Darwin Notification。参数: token (number) - 监听 token 返回: boolean - 是否取消成功
// 取消监听
const success = app.notifyCancel(token);
if (success) {
console.log('取消监听成功');
}
完整示例:进程间通信
// 进程 A:注册监听
const token = app.notifyRegister('com.example.data.updated');
console.log('开始监听数据更新通知');
// 进程 B:发送通知
app.notifyPost('com.example.data.updated');
// 进程 A:取消监听
app.notifyCancel(token);
注意: Darwin Notification 是系统级通知,适用于跨进程通信。通知名称建议使用反向域名格式(如
com.example.notification)以避免冲突。
完整示例¶
示例 1: 应用信息显示¶
const info = app.info();
console.log('=== 应用信息 ===');
console.log(`名称: ${info.name}`);
console.log(`版本: ${info.version} (${info.build})`);
console.log(`Bundle ID: ${info.bundleId}`);
console.log(`语言: ${info.language}`);
示例 2: 日志导出¶
function exportLogsToFile() {
const logs = app.exportLogs();
const filename = `logs_${util.formatDate(Date.now(), 'yyyyMMdd_HHmmss')}.txt`;
file.write(`/var/mobile/Documents/${filename}`, logs);
console.log('日志已导出:', filename);
}
示例 3: 应用启动器¶
function launchApp(bundleId) {
if (!app.isInstalled(bundleId)) {
console.error('应用未安装');
return false;
}
const success = app.launch(bundleId);
if (success) {
console.log('应用已启动');
} else {
console.error('启动失败');
}
return success;
}
launchApp('com.apple.mobilesafari');
示例 4: 崩溃监控¶
function checkCrashes() {
const lastCrash = app.getLastCrash();
if (lastCrash) {
const crashTime = new Date(lastCrash.date * 1000);
const now = Date.now();
const hoursSinceCrash = (now - lastCrash.date * 1000) / (1000 * 60 * 60);
if (hoursSinceCrash < 24) {
notification.send('应用崩溃', `最近发生崩溃: ${lastCrash.reason}`);
}
}
}
示例 5: 应用管理器¶
class AppManager {
listApps() {
return app.list();
}
findApp(keyword) {
const apps = this.listApps();
return apps.filter(a =>
a.name.includes(keyword) || a.bundleId.includes(keyword)
);
}
launchByName(name) {
const apps = this.findApp(name);
if (apps.length === 0) {
console.error('未找到应用');
return false;
}
return app.launch(apps[0].bundleId);
}
}
const manager = new AppManager();
manager.launchByName('Safari');
最佳实践¶
1. 检查应用是否安装¶
// ✅ 正确
if (app.isInstalled('com.apple.mobilesafari')) {
app.launch('com.apple.mobilesafari');
}
// ❌ 错误
app.launch('com.apple.mobilesafari'); // 可能失败
2. 处理 URL 打开失败¶
// ✅ 正确
if (app.canOpen(url)) {
app.open(url);
} else {
console.error('无法打开 URL');
}
3. 定期清理日志¶
// ✅ 正确 - 定期清理
const logs = app.getLogs();
if (logs.length > 1000) {
app.clearLogs();
}
4. 安全使用私有 API¶
// ✅ 正确 - 检查返回值
const apps = app.list();
if (apps && apps.length > 0) {
// 处理应用列表
}
注意事项¶
- 私有 API: 应用管理功能使用私有 API,需要 TrollStore 权限
- Daemon 限制:
openSettings在 Daemon 模式下不可用 - 权限要求: 某些操作需要特殊权限
- 系统限制: 无法终止系统应用
- Bundle ID: 需要准确的 Bundle ID 才能操作应用
- 日志大小: 日志会占用存储空间,建议定期清理
- 崩溃报告: 仅记录应用自身的崩溃
- 线程安全: 所有 API 都是线程安全的