Tornaco / Thanox

I am thanos! 😈 👌
https://tornaco.github.io/Thanox-Docs/
Apache License 2.0
1.96k stars 81 forks source link

Try to suspend the process--墓碑模式探索 #455

Open countrysideboy opened 2 years ago

countrysideboy commented 2 years ago

如题,觉得目前的乖巧模式的不太压得住流氓们,app切换到后台后仍然占用cpu,于是探索使用冻结进程的方式,看作者大神后续能否增强(需要那种前台能用,后台压得死死的,切换回前台又恢复之前的会话)

在全局变量中添加 pause,把要压制的app添加进去;或者在目标应用详情,将电池设置为受限(为了检验效果,脚本与乖巧模式互斥,会自动关闭乖巧)

20220729更新: 1.修复未添加全局变量pause时脚本出错的bug; 2.添加参数自定义调整功能,其中DELAY = 45000,对应实现应用切回后台进入墓碑的等待时长(毫秒);修改为SU_EXE = 1,则使用kill -19命令来压制进程,需打开su插件支持(默认SU_EXE = 0,使用系统api进行压制,无需su插件)。 情景模式脚本

[
  {
        "name": "ForceIdle: auto pause or continue App",
        "description": "通过全局变量[pause]添加应用列表,或设置电池用量为受限,对回到后台的应用强制压制(墓碑)。\nForce pause the app while it switchs to backgroud, you need to pick app list in the global val name [pause].",
        "priority": 1,
        "condition": "frontPkgChanged == true",
        "actions": [
            "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
            "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
            "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
            "if(context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to) == android.app.AppOpsManager.MODE_IGNORED || (thanos.getProfileManager().isGlobalRuleVarByNameExists(\"pause\") && globalVarOf$pause.contains(to))){foreach(proc:context.getSystemService(context.ACTIVITY_SERVICE).getRunningAppProcesses()){if(proc.processName.contains(to)){android.os.Process.sendSignal(proc.pid,18);}}; context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT); context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(to,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE); if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)}; if(thanos.getActivityManager().isPkgBgRestricted(to)){thanos.getActivityManager().setPkgBgRestrictEnabled(to,false)}};",
            "DELAY = 45000; if(context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from) == android.app.AppOpsManager.MODE_IGNORED || (thanos.getProfileManager().isGlobalRuleVarByNameExists(\"pause\") && globalVarOf$pause.contains(from))){context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED); thanos.getActivityManager().setBlockAllService(from,true); thanos.getActivityManager().setBlockAllReceiver(from,true); thanos.getActivityManager().setBlockAllProvider(from,true); actor.delayed(DELAY,\"if(activity.getFrontAppPackage()!=from){if(thanos.getActivityManager().isPackageIdle(from)==false){context.getSystemService(context.ACTIVITY_SERVICE).getService().makePackageIdle(from,android.os.UserHandle.USER_ALL)}; if(activity.isInactive(from)==false){activity.setInactive(from)}; context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(from,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED); SU_EXE = 0; foreach(proc:context.getSystemService(context.ACTIVITY_SERVICE).getRunningAppProcesses()){if(proc.processName.contains(from)){if(SU_EXE == 1){su.exe(\\\"kill -19 \\\" + proc.pid);};if(SU_EXE != 1){android.os.Process.sendSignal(proc.pid,20);};}}}\")};"
         ]
     }
]
countrysideboy commented 2 years ago

目前已知问题: 1.好像压不住关联唤醒,压不住广播 2.使用冻结进程的方式,原脚本是用kill -19的方式,现在换成cgroup feeeze的方式,但从日志看,进程似乎仍会anr。

也许要写Xposed模块hook相关操作才能搞定上面的问题,但要处理后台自启,广播,wakelock,alarm,想想就麻烦,期待作者出暴力压制模式。目前thanox的权限管理够好用了,要是能压制后台,原生系统就更省电了。

Tornaco commented 2 years ago

都是人才啊,我会抽时间学习研究一下。

Tornaco commented 2 years ago

我编辑了一下这个issue,调整了一下代码格式化。

tzfljuv commented 2 years ago

最近我恰好在探索相关内容,但无奈自己没有安卓开发的能力,目前仅能做到脚本级别的冰冻后台(效率极度低下,基本就是暴力轮询)。Thanox在安卓平台层面应该能更好地处理相关功能实现。

@countrysideboy 你应该用到了cgroupv2的freezer功能,这个功能要求内核版本大于5.4、或者OEM将相关功能移植回低版本内核。而如果你的内核本来就支持了cgroupv2的freezer,那么你可以前往开发者选项 -> 对缓存应用暂停执行(Suspend execution for cached apps)

相关功能分析: https://juejin.cn/post/7078957393446453285

kill -SIGCONT会导致父进程异常,相关问题介绍: https://www.kernel.org/doc/Documentation/cgroup-v1/freezer-subsystem.txt 但不知道先用freezer冻结之后再用SIGSTOP冻结,并且在唤醒时先用SIGCONT解除掉SIGSTOP、再把freezer的冰冻状态解除,这样能不能规避父进程崩溃的问题。

@Tornaco cgroupv2 freezer有较高的内核版本要求,请考虑一下如果cgroupv2 freezer不可用的时候fallback回cgroupv1 freezer(支持这个的设备应该更加广泛)

freezer冻结和解冻请以整个应用为单位来进行,不然可能发生异常,比如应用的其它进程的异常捕捉认为应用未响应了于是尝试重启应用(脚本里的逐个pid冰冻是有问题的)。更好的做法是创建一个新的cgroup,并以应用包(或uid)为单位划分,冻结时将整个节点冻结而不是单独一个一个pid来。

最后,如果有其它通讯平台的联系方式可能会更方便些。

countrysideboy commented 2 years ago

看来研究得很深入啊。一开始我是直接冻结整个uid 而非pid,但是发现应用异常退出后,无论是否解冻,app都无法再打开,很奇怪,才转而冻结pid

countrysideboy commented 2 years ago

至于kill -19的方式,可能比较通用,但会anr,我试过去hook相关函数但没有成功。

另外就算能冻结成功,唤醒锁,闹钟,广播需要解决,不然还是会被关联唤醒。

myflavor commented 2 years ago

通过Hook安卓系统屏蔽ANR Screenshot_2022-05-03-08-02-14-587_me simpleHook

myflavor commented 2 years ago
[
    {
        "name": "冻结进程",
        "description": "当应用进入后台时冻结进程",
        "priority": 1,
        "condition": "frontPkgChanged == true && thanos.getActivityManager().isPkgSmartStandByEnabled(from)==true && !globalVarOf$whiteApps.contains(from)",
        "actions": [
            "su.exe(\"appops set \" +from + \" RUN_ANY_IN_BACKGROUND ignore\");",
            "su.exe(\"appops set \" +from + \" RUN_IN_BACKGROUND ignore\");",
            "su.exe(\"appops set \" +from + \" WAKE_LOCK ignore\");",
            "activity.setInactive(from);",
            "su.exe(\"am make-uid-idle \" +from);",
            "su.exe(\"am set-standby-bucket \" +from +\" restricted\");", "actor.delayed(2000,\"if(activity.getFrontAppPackage()!=from){su.exe(\\\"kill -19 `pgrep -f \\\"+ from+ \\\"`\\\")}\");"
        ]
    }
]

[
    {
        "name": "解冻进程",
        "description": "当应用进入前台时解冻进程",
        "priority": 1,
        "condition": "frontPkgChanged == true && thanos.getActivityManager().isPkgSmartStandByEnabled(to)==true && !globalVarOf$whiteApps.contains(to)",
        "actions": [
            "su.exe(\"appops set \" +to + \" RUN_ANY_IN_BACKGROUND default\");",
            "su.exe(\"appops set \" +to + \" RUN_IN_BACKGROUND default\");",
            "su.exe(\"appops set \" +to + \" WAKE_LOCK default\");",
"su.exe(\"kill -18 `pgrep -f \"+ to + \"`\");",
            "su.exe(\"am set-standby-bucket \" +to +\" rare\");"
        ]
    }
]
countrysideboy commented 2 years ago

以下为使用kill方式冻结的脚本,做了一些禁用广播接收器方面的尝试

情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(to)",
    "actions": [
    "su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\");",
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)};",
    "su.exe(\"am set-standby-bucket \" +to +\" rare\");"
    ]
  }
]

情景模式脚本2

[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(from) && activity.getFrontAppPackage()!=\"android\" ",
    "actions": [ 
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "if(thanos.getActivityManager().isBlockAllService(from)==false){thanos.getActivityManager().setBlockAllService(from,true)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(from)==false){thanos.getActivityManager().setBlockAllReceiver(from,true)};",
    "if(thanos.getActivityManager().isBlockAllProvider(from)==false){thanos.getActivityManager().setBlockAllProvider(from,true)};",
    "su.exe(\"am send-trim-memory \" +from+ \" TRIM_MEMORY_RUNNING_CRITICAL\");",
    "if(activity.isInactive(from)==false){activity.setInactive(from)};",
    "if(thanos.getActivityManager().isPackageIdle(from)==false){thanos.getActivityManager().idlePackage(from)};",
    "actor.delayed(15000,\"if(activity.getFrontAppPackage()!=from){su.exe(\\\"am make-uid-idle \\\" +from);su.exe(\\\"am set-standby-bucket \\\" +from +\\\" restricted\\\");su.exe(\\\"kill -STOP `pgrep -f \\\"+ from+ \\\"`\\\")}\");"
    ] 
  }
]

已更新,希望最终能不用su.exe,调用系统api实现,比如sendsignal等

myflavor commented 2 years ago

OP_WAKE_LOCK应该是没用的 OP_RUN_ANY_IN_BACKGROUND比OP_RUN_IN_BACKGROUND限制多 下面的广播服务提供者阻止,不知道没有NoANR能不能正常了

countrysideboy commented 2 years ago

OP_WAKE_LOCK应该是没用的 OP_RUN_ANY_IN_BACKGROUND比OP_RUN_IN_BACKGROUND限制多 下面的广播服务提供者阻止,不知道没有NoANR能不能正常了

初步测试了一下,不使用NoANR模块好像可以,thanox作者似乎有处理这个问题。

myflavor commented 2 years ago

有看过/data/anr的日志吗

myflavor commented 2 years ago

也不知道Thanox怎么阻止的广播,我的NoANR是在分到APP之前去掉了广播,但是已经在执行的广播没去干扰,看这个情景模式也是延迟了15s,前台广播超时好像是10s,这样应该不存在后台后还有广播在执行了

countrysideboy commented 2 years ago

有看过/data/anr的日志吗

昨天我把文件清空了,要测久一点才能确认了

myflavor commented 2 years ago

冻结APP之后,直接锁屏,触发息屏广播,过个几秒,看看/data/anr有没有日志,如果有就是广播阻止的不彻底,如果没有,广播就成功阻止了,然后还有服务的ANR,就是挂后台,挂久一点,如果没有出现,那就没啥问题了,提供者的ANR我没看过了,NoANR去掉广播之后,屏蔽NoANR就没有任何问题了,所以我就没继续研究了

myflavor commented 2 years ago

用Thanox的阻止广播还有服务和提供者,会导致比如美团支付使用支付宝,而支付宝以及被阻止了,就会显示找不到支付宝

countrysideboy commented 2 years ago

用Thanox的阻止广播还有服务和提供者,会导致比如美团支付使用支付宝,而支付宝以及被阻止了,就会显示找不到支付宝

是吧,我试了下闲鱼跳转淘宝授权登录,好像也不行

countrysideboy commented 2 years ago

冻结APP之后,直接锁屏,触发息屏广播,过个几秒,看看/data/anr有没有日志,如果有就是广播阻止的不彻底,如果没有,广播就成功阻止了,然后还有服务的ANR,就是挂后台,挂久一点,如果没有出现,那就没啥问题了,提供者的ANR我没看过了,NoANR去掉广播之后,屏蔽NoANR就没有任何问题了,所以我就没继续研究了

测试了几下,暂时没发现有文件。

myflavor commented 2 years ago

还有就是,感觉15s延迟是不是太久了,进入后台那一会是最活跃的,如果改成3s还能不能正常,会不会就触发ANR了

countrysideboy commented 2 years ago

还有就是,感觉15s延迟是不是太久了,进入后台那一会是最活跃的,如果改成3s还能不能正常,会不会就触发ANR了

我试试。等待时间久些,是希望程序能进缓存。之前测试,短时间内发送make-uid-idle没有效果,要有那么一段时间后执行才有效

hanxin1997 commented 2 years ago

以下为使用kill方式冻结的脚本,做了一些禁用广播接收器方面的尝试 情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(to)",
    "actions": [
    "su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\");",
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)};",
    "su.exe(\"am set-standby-bucket \" +to +\" rare\");"
    ]
  }
]

情景模式脚本2

[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(from) && activity.getFrontAppPackage()!=\"android\" ",
    "actions": [ 
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "if(thanos.getActivityManager().isBlockAllService(from)==false){thanos.getActivityManager().setBlockAllService(from,true)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(from)==false){thanos.getActivityManager().setBlockAllReceiver(from,true)};",
    "if(thanos.getActivityManager().isBlockAllProvider(from)==false){thanos.getActivityManager().setBlockAllProvider(from,true)};",
    "su.exe(\"am send-trim-memory \" +from+ \" TRIM_MEMORY_RUNNING_CRITICAL\");",
    "if(activity.isInactive(from)==false){activity.setInactive(from)};",
    "if(thanos.getActivityManager().isPackageIdle(from)==false){thanos.getActivityManager().idlePackage(from)};",
    "actor.delayed(15000,\"if(activity.getFrontAppPackage()!=from){su.exe(\\\"am make-uid-idle \\\" +from);su.exe(\\\"am set-standby-bucket \\\" +from +\\\" restricted\\\");su.exe(\\\"kill -STOP `pgrep -f \\\"+ from+ \\\"`\\\")}\");"
    ] 
  }
]

已更新,希望最终能不用su.exe,调用系统api实现,比如sendsignal等

发现如果直接把全局变量的软件取消后会出现奇怪的问题 比如qq和微信是连不上网 接不到新消息,停止应用和重新开机都不行恢复,只有停止冻结的那个情景模式,而且解冻的那个情景模式得开启,再打开一次软件才恢复正常,如果有人看到这个问题,请使用这个方法恢复app。

myflavor commented 2 years ago

这个问题就是阻止广播还有服务以及提供者导致的,你可以关闭冻结脚本,开一遍被冻结过的脚本,然后移除冻结名单

countrysideboy commented 2 years ago

写了一版比较特殊的版本,不需要su.exe插件,不需要添加全局变量了(以前的脚本需要添加pause变量且加入app列表)。 开关应用是否墓碑的方式为:使用系统自带的电池设置,将目标app的“管理电池用量”设置为“受限”即可。 缺点是无法批量添加app,提供一种思路,权当系统鸡肋电量限制模式的增强版。 备注:需要安卓10以上。

情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true",
    "actions": [
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "if(context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to) == android.app.AppOpsManager.MODE_IGNORED){foreach(proc:context.getSystemService(context.ACTIVITY_SERVICE).getRunningAppProcesses()){if(proc.processName.contains(to)){android.os.Process.sendSignal(proc.pid,18);}}; context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT); context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(to,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE)}; if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)}; if(thanos.getActivityManager().isPkgBgRestricted(to)){thanos.getActivityManager().setPkgBgRestrictEnabled(to,false)};"
    ]
  }
]

情景模式脚本2


[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from) == android.app.AppOpsManager.MODE_IGNORED",
    "actions": [
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "thanos.getActivityManager().setBlockAllService(from,true);",
    "thanos.getActivityManager().setBlockAllReceiver(from,true);",
    "thanos.getActivityManager().setBlockAllProvider(from,true);",
    "actor.delayed(15000,\"if(activity.getFrontAppPackage()!=from){if(thanos.getActivityManager().isPackageIdle(from)==false && android.os.Build.VERSION.SDK_INT < 32){context.getSystemService(context.ACTIVITY_SERVICE).getService().makePackageIdle(from,android.os.UserHandle.USER_ALL)};if(activity.isInactive(from)==false && android.os.Build.VERSION.SDK_INT < 32){activity.setInactive(from)};context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(from,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED);foreach(proc:context.getSystemService(context.ACTIVITY_SERVICE).getRunningAppProcesses()){if(proc.processName.contains(from)){android.os.Process.sendSignal(proc.pid,20);}}}\");"
    ] 
  }
]
Teddy-Zhu commented 2 years ago

以下为使用kill方式冻结的脚本,做了一些禁用广播接收器方面的尝试 情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(to)",
    "actions": [
    "su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\");",
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)};",
    "su.exe(\"am set-standby-bucket \" +to +\" rare\");"
    ]
  }
]

情景模式脚本2

[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(from) && activity.getFrontAppPackage()!=\"android\" ",
    "actions": [ 
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "if(thanos.getActivityManager().isBlockAllService(from)==false){thanos.getActivityManager().setBlockAllService(from,true)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(from)==false){thanos.getActivityManager().setBlockAllReceiver(from,true)};",
    "if(thanos.getActivityManager().isBlockAllProvider(from)==false){thanos.getActivityManager().setBlockAllProvider(from,true)};",
    "su.exe(\"am send-trim-memory \" +from+ \" TRIM_MEMORY_RUNNING_CRITICAL\");",
    "if(activity.isInactive(from)==false){activity.setInactive(from)};",
    "if(thanos.getActivityManager().isPackageIdle(from)==false){thanos.getActivityManager().idlePackage(from)};",
    "actor.delayed(15000,\"if(activity.getFrontAppPackage()!=from){su.exe(\\\"am make-uid-idle \\\" +from);su.exe(\\\"am set-standby-bucket \\\" +from +\\\" restricted\\\");su.exe(\\\"kill -STOP `pgrep -f \\\"+ from+ \\\"`\\\")}\");"
    ] 
  }
]

已更新,希望最终能不用su.exe,调用系统api实现,比如sendsignal等

发现如果直接把全局变量的软件取消后会出现奇怪的问题 比如qq和微信是连不上网 接不到新消息,停止应用和重新开机都不行恢复,只有停止冻结的那个情景模式,而且解冻的那个情景模式得开启,再打开一次软件才恢复正常,如果有人看到这个问题,请使用这个方法恢复app。

这个阻止广播还有服务以及提供者还会因为开关vpn之后网络异常, 副作用挺大的 , 比如软件开着vpn 回到桌面, 关闭vpn,15s后再打开软件,软件依旧无法上网,需要重新打开vpn之后才能正常连接网络

countrysideboy commented 2 years ago

以下为使用kill方式冻结的脚本,做了一些禁用广播接收器方面的尝试 情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(to)",
    "actions": [
    "su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\");",
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT);",
    "if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)};",
    "su.exe(\"am set-standby-bucket \" +to +\" rare\");"
    ]
  }
]

情景模式脚本2

[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && globalVarOf$pause.contains(from) && activity.getFrontAppPackage()!=\"android\" ",
    "actions": [ 
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_RUN_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "if(thanos.getActivityManager().isBlockAllService(from)==false){thanos.getActivityManager().setBlockAllService(from,true)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(from)==false){thanos.getActivityManager().setBlockAllReceiver(from,true)};",
    "if(thanos.getActivityManager().isBlockAllProvider(from)==false){thanos.getActivityManager().setBlockAllProvider(from,true)};",
    "su.exe(\"am send-trim-memory \" +from+ \" TRIM_MEMORY_RUNNING_CRITICAL\");",
    "if(activity.isInactive(from)==false){activity.setInactive(from)};",
    "if(thanos.getActivityManager().isPackageIdle(from)==false){thanos.getActivityManager().idlePackage(from)};",
    "actor.delayed(15000,\"if(activity.getFrontAppPackage()!=from){su.exe(\\\"am make-uid-idle \\\" +from);su.exe(\\\"am set-standby-bucket \\\" +from +\\\" restricted\\\");su.exe(\\\"kill -STOP `pgrep -f \\\"+ from+ \\\"`\\\")}\");"
    ] 
  }
]

已更新,希望最终能不用su.exe,调用系统api实现,比如sendsignal等

发现如果直接把全局变量的软件取消后会出现奇怪的问题 比如qq和微信是连不上网 接不到新消息,停止应用和重新开机都不行恢复,只有停止冻结的那个情景模式,而且解冻的那个情景模式得开启,再打开一次软件才恢复正常,如果有人看到这个问题,请使用这个方法恢复app。

这个阻止广播还有服务以及提供者还会因为开关vpn之后网络异常, 副作用挺大的 , 比如软件开着vpn 回到桌面, 关闭vpn,15s后再打开软件,软件依旧无法上网,需要重新打开vpn之后才能正常连接网络

如果是这样,或许可以触发一个网络连接变化的广播

Moderpach commented 2 years ago

现在thanox能实现识别显示在应用上层的服务和前台服务以防止这些应用被墓碑吗

countrysideboy commented 2 years ago

现在thanox能实现识别显示在应用上层的服务和前台服务以防止这些应用被墓碑吗

不清楚,暂时没找到方法

countrysideboy commented 2 years ago

写了一版比较特殊的版本,不需要添加全局变量了(以前的脚本需要添加pause变量且加入app列表)。 开关应用是否墓碑的方式为:使用系统自带的电池设置,将目标app的“管理电池用量”设置为“受限”即可。 缺点是无法批量添加app,提供一种思路,权当系统鸡肋电量限制模式的增强版。 备注:需要安卓10以上。

情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true ",
    "actions": [
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "if(context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to) == android.app.AppOpsManager.MODE_IGNORED){su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\"); context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT); if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)}; context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(to,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE)};"
    ]
  }
]

情景模式脚本2

[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from) == android.app.AppOpsManager.MODE_IGNORED ",
    "actions": [ 
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "thanos.getActivityManager().setBlockAllService(from,true);",
    "thanos.getActivityManager().setBlockAllReceiver(from,true);",
    "thanos.getActivityManager().setBlockAllProvider(from,true);",
    "if(activity.isInactive(from)==false){activity.setInactive(from)};",
    "if(thanos.getActivityManager().isPackageIdle(from)==false){context.getSystemService(context.ACTIVITY_SERVICE).getService().makePackageIdle(from,android.os.UserHandle.USER_ALL)};",
    "actor.delayed(1500,\"if(activity.getFrontAppPackage()!=from){context.getSystemService(context.ACTIVITY_SERVICE).getService().makePackageIdle(from,android.os.UserHandle.USER_ALL); context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(from,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED);su.exe(\\\"kill -STOP `pgrep -f \\\"+ from+ \\\"`\\\")}\");"
    ] 
  }
]

20220602:这是我目前自己在用的版本,会自动关闭乖巧,通过设置某个app的电池限制模式来决定是否墓碑

Tornaco commented 2 years ago

现在thanox能实现识别显示在应用上层的服务和前台服务以防止这些应用被墓碑吗

3.9.9 新增 API可以识别应用是否有可见window,可用于判断其是否有悬浮窗展示。

android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/wm/WindowManager.java

@SneakyThrows
    public List<WindowState> getVisibleWindows() {
        return server.getVisibleWindows();
    }

    @SneakyThrows
    public boolean hasVisibleWindows(String pkgName) {
        return getVisibleWindows().stream().anyMatch(windowState -> windowState.packageName.equals(pkgName));
    }

    @SneakyThrows
    public boolean hasVisibleWindows(Pkg pkg) {
        return getVisibleWindows().stream().anyMatch(windowState -> windowState.packageName.equals(pkg.getPkgName())
                && UserHandle.getUserId(windowState.uid) == pkg.getUserId());
    }

示例:

action: "if (thanos.windowManager.hasVisibleWindows(xxxxx.xxx.xxx)) ..."
myflavor commented 2 years ago

这样确实可以避免app被冻结了,不过小窗程序在进入后台,不会触发任何条件,这个不知道有没有什么好的办法了

myflavor commented 2 years ago

搭配NoANR2.2

[ { "name": "冻结进程", "description": "当应用进入后台时冻结进程", "priority": 1, "condition": "frontPkgChanged == true && thanos.getActivityManager().isPkgSmartStandByEnabled(from) && !globalVarOf$whiteApps.contains(from)", "actions": [ "su.exe(\"appops set \" +from + \" WAKE_LOCK ignore\");", "do{Thread.sleep(1000)}until(activity.getFrontAppPackage()!=\"android\");", "actor.delayed(1000,\"if(!thanos.windowManager.hasVisibleWindows(from)){su.exe(\\"kill -STOP pgrep -f \\\"+ from+ \\\"\\")}\");" ] } ]

[ { "name": "解冻进程", "description": "当应用进入前台时解冻进程", "priority": 1, "condition": "frontPkgChanged == true && thanos.getActivityManager().isPkgSmartStandByEnabled(to) && !globalVarOf$whiteApps.contains(to)", "actions": [ "su.exe(\"kill -CONT pgrep -f \"+ to + \"\");", "su.exe(\"appops set \" +to + \" WAKE_LOCK default\");" ] } ]

myflavor commented 2 years ago

github原来也会自动转义啊。。。。 帖一个我的博客 Thanox3.9.9墓碑情景模式

myflavor commented 2 years ago

真正的乖巧增强模式,使用foreach遍历乖巧规则 顺便提一下有人反馈thanos.windowManager.hasVisibleWindows存在不准确的情况 由于我这边是没问题的,所以没法提供相关信息 但是可以在判断可见api前,先判断activity.getFrontAppPackage

[
    {
        "name": "解冻进程",
        "description": "当应用进入前台时解冻进程",
        "priority": 1,
        "condition": "frontPkgChanged && thanos.getActivityManager().isPkgSmartStandByEnabled(to)",
        "actions": [
            "su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\");",
            "su.exe(\"appops set \" +to + \" WAKE_LOCK default\");"
        ]
    }
]
[
    {
        "name": "冻结进程(AppOps)",
        "description": "当应用进入后台时设置AppOps",
        "priority": 1,
        "condition": "frontPkgChanged && thanos.getActivityManager().isPkgSmartStandByEnabled(from)",
        "actions": [
            "foreach (rule : thanos.getActivityManager().getAllStandbyRules()){if(rule.startsWith(\"KEEP\") && rule.contains(from + \"/\")){break}}",
            "su.exe(\"appops set \" + from + \" WAKE_LOCK ignore\");"
        ]
    }
]

[
    {
        "name": "冻结进程",
        "description": "当应用进入后台时冻结进程",
        "priority": 2,
        "delay": 2000,
        "condition": "frontPkgChanged && thanos.getActivityManager().isPkgSmartStandByEnabled(from)",
        "actions": [
            "foreach (rule : thanos.getActivityManager().getAllStandbyRules()){if(rule.startsWith(\"KEEP\") && rule.contains(from + \"/\")){break}}",
            "if(activity.getFrontAppPackage()!=from && !thanos.windowManager.hasVisibleWindows(from)){su.exe(\"kill -STOP `pgrep -f \"+ from +\"`\")};"
        ]
    }
]
myflavor commented 2 years ago
[
    {
        "name": "墓碑后台",
        "description": "冻结乖巧应用后台",
        "priority": -1,
        "condition": "frontPkgChanged",
        "actions": [
            "if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){su.exe(\"kill -CONT `pgrep -f \"+ to + \"`\");su.exe(\"appops set \" +to + \" WAKE_LOCK default\")}",
            "if(!thanos.getActivityManager().isPkgSmartStandByEnabled(from)){break}",
            "foreach (rule : thanos.getActivityManager().getAllStandbyRules()){if(rule.startsWith(\"KEEP\") && rule.contains(from + \"/\")){break}}",
            "su.exe(\"appops set \" + from + \" WAKE_LOCK ignore\");"
            "Thread.sleep(2000);",
            "if(activity.getFrontAppPackage()!=from && !thanos.windowManager.hasVisibleWindows(from)){su.exe(\"kill -STOP `pgrep -f \"+ from +\"`\")};"
        ]
    }
]
countrysideboy commented 2 years ago

写了一版比较特殊的版本,不需要su.exe插件,不需要添加全局变量了(以前的脚本需要添加pause变量且加入app列表)。 开关应用是否墓碑的方式为:使用系统自带的电池设置,将目标app的“管理电池用量”设置为“受限”即可。 缺点是无法批量添加app,提供一种思路,权当系统鸡肋电量限制模式的增强版。 备注:需要安卓10以上。

情景模式脚本1

[
  {
    "name": "ForceIdle: continue App",
    "description": "切回前台,取消压制",
    "priority": 1,
    "condition": "frontPkgChanged == true",
    "actions": [
    "if(thanos.getActivityManager().isBlockAllService(to)){thanos.getActivityManager().setBlockAllService(to,false)};",
    "if(thanos.getActivityManager().isBlockAllReceiver(to)){thanos.getActivityManager().setBlockAllReceiver(to,false)};",
    "if(thanos.getActivityManager().isBlockAllProvider(to)){thanos.getActivityManager().setBlockAllProvider(to,false)};",
    "if(context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(to), to) == android.app.AppOpsManager.MODE_IGNORED){foreach(proc:thanos.getActivityManager().getRunningAppProcess()){if(proc.packageName!=null && proc.packageName==to){android.os.Process.sendSignal(proc.pid,18);}}; context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(to), to, android.app.AppOpsManager.MODE_DEFAULT); context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(to,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE)}; if(thanos.getActivityManager().isPkgSmartStandByEnabled(to)){thanos.getActivityManager().setPkgSmartStandByEnabled(to,false)}; if(thanos.getActivityManager().isPkgBgRestricted(to)){thanos.getActivityManager().setPkgBgRestrictEnabled(to,false)};"
    ]
  }
]

情景模式脚本2

[
  {
    "name": "ForceIdle: pause App",
    "description": "切到后台,自动压制",
    "priority": 2,
    "condition": "frontPkgChanged == true && context.getSystemService(context.APP_OPS_SERVICE).unsafeCheckOp(android.app.AppOpsManager.OPSTR_RUN_ANY_IN_BACKGROUND, thanos.getPkgManager().getUidForPkgName(from), from) == android.app.AppOpsManager.MODE_IGNORED",
    "actions": [
    "context.getSystemService(context.APP_OPS_SERVICE).setMode(android.app.AppOpsManager.OP_WAKE_LOCK, thanos.getPkgManager().getUidForPkgName(from), from, android.app.AppOpsManager.MODE_IGNORED);",
    "thanos.getActivityManager().setBlockAllService(from,true);",
    "thanos.getActivityManager().setBlockAllReceiver(from,true);",
    "thanos.getActivityManager().setBlockAllProvider(from,true);",
    "if(activity.isInactive(from)==false){activity.setInactive(from)};",
    "if(thanos.getActivityManager().isPackageIdle(from)==false){context.getSystemService(context.ACTIVITY_SERVICE).getService().makePackageIdle(from,android.os.UserHandle.USER_ALL)};",
    "actor.delayed(15000,\"if(activity.getFrontAppPackage()!=from){context.getSystemService(context.ACTIVITY_SERVICE).getService().makePackageIdle(from,android.os.UserHandle.USER_ALL); context.getSystemService(context.USAGE_STATS_SERVICE).setAppStandbyBucket(from,android.app.usage.UsageStatsManager.STANDBY_BUCKET_RESTRICTED);foreach(proc:thanos.getActivityManager().getRunningAppProcess()){if(proc.packageName!=null && proc.packageName==from){android.os.Process.sendSignal(proc.pid,20);}}}\");"
    ] 
  }
]

已更新,不需要su.exe了,全api实现,也就是说,thanox不用常驻后台了

simplerick-simplefun commented 1 year ago

感谢大佬们。 想问一下,android.os.Process.sendSignal(proc.pid,sig) 这个我无法运行是什么情况?经过确认proc.pid可以正常获取。就是这个function无法运行。

myflavor commented 1 year ago

@simplerick-simplefun 19不行的话,试试20,再不行就用su吧

simplerick-simplefun commented 1 year ago

@simplerick-simplefun 19不行的话,试试20,再不行就用su吧

不是sig的问题,我试了3和9都不行。3和9都是documented。 su可以用。

public static final int SIGNAL_QUIT = 3;
public static final int SIGNAL_KILL = 9;
public static final int SIGNAL_USR1 = 10;
countrysideboy commented 1 year ago

@simplerick-simplefun 19不行的话,试试20,再不行就用su吧

不是sig的问题,我试了3和9都不行。3和9都是documented。 su可以用。

public static final int SIGNAL_QUIT = 3;
public static final int SIGNAL_KILL = 9;
public static final int SIGNAL_USR1 = 10;

那就暂时只能su了。如果是cgroupv2,或许可以调用thanox自带的api

Gokou-Ruri commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

simplerick-simplefun commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

countrysideboy commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

我怀疑就是基带耗电,因为实验机不插卡只开着wifi也挺省电。另外,理论上说,暂停了进程,应该对app来说网络活动也暂停,不走流量的

Gokou-Ruri commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

simplerick-simplefun commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

拔掉sim卡,或者直接在手机里面禁用sim,比如飞行模式,确实可以省电,但是这样就无法接打电话了。 保留电话信号的话,应用使用网络流量带来的耗电则是可以忽略的;主要是要限制唤醒和后台前台服务。

Gokou-Ruri commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

拔掉sim卡,或者直接在手机里面禁用sim,比如飞行模式,确实可以省电,但是这样就无法接打电话了。 保留电话信号的话,应用使用网络流量带来的耗电则是可以忽略的;主要是要限制唤醒和后台前台服务。

牛头不对马嘴的回复,能请您看完别人打的字再回吗?如果您不看就回,就请您不要再回了,您是把github issues当论坛闲聊板块了吗?

simplerick-simplefun commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

我怀疑就是基带耗电,因为实验机不插卡只开着wifi也挺省电。另外,理论上说,暂停了进程,应该对app来说网络活动也暂停,不走流量的

基带耗电基本是确定了的。可以搜一下,有这方面的新闻。

simplerick-simplefun commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

拔掉sim卡,或者直接在手机里面禁用sim,比如飞行模式,确实可以省电,但是这样就无法接打电话了。 保留电话信号的话,应用使用网络流量带来的耗电则是可以忽略的;主要是要限制唤醒和后台前台服务。

牛头不对马嘴的回复,能请您看完别人打的字再回吗?如果您不看就回,就请您不要再回了,您是把github issues当论坛闲聊板块了吗?

是你自己讲: 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。 我给你的回复是说你的这个思路在实际使用中没有用处。你拔了sim就不用让那些app认为无网络。你插上sim让那些app认为无网络也不省电,因为基带保持电话信号就是耗电的主体,而使用这个信号于一些后台app的网络流量对于基带维持信号的耗电相比可以忽略。更何况大部分人不可能拔sim,大家要接电话的。 我讲的wifi环境,指得是插上sim有手机电信信号(5G/4G/3G)情况下,手机连接了wifi的环境。我觉得是你没读清楚。一般这种话题讲“wifi环境”,都不是指纯wifi不连电信信号。那么你电信有信号,wifi有连接,后台app跑流量是走wifi对吧。那我讲这种情况下也有基带的耗电,意思就是这个app后台流量与基带耗电的关系不大。 然后你后面又跟我回复说要拔sim。我才跟你讲大家要接打电话,拔sim不现实。 这样说是否清楚?

Gokou-Ruri commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

拔掉sim卡,或者直接在手机里面禁用sim,比如飞行模式,确实可以省电,但是这样就无法接打电话了。 保留电话信号的话,应用使用网络流量带来的耗电则是可以忽略的;主要是要限制唤醒和后台前台服务。

牛头不对马嘴的回复,能请您看完别人打的字再回吗?如果您不看就回,就请您不要再回了,您是把github issues当论坛闲聊板块了吗?

是你自己讲: 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。 我给你的回复是说你的这个思路在实际使用中没有用处。你拔了sim就不用让那些app认为无网络。你插上sim让那些app认为无网络也不省电,因为基带保持电话信号就是耗电的主体,而使用这个信号于一些后台app的网络流量对于基带维持信号的耗电相比可以忽略。更何况大部分人不可能拔sim,大家要接电话的。 这样说是否清楚?

谁告诉您基带待机很费电的?恢复出厂后4g待机就挺省电的,安装一大堆软件后待机就很费电,拔sim卡后待机特别省电,这还不能说明问题?您去看看运营商规定的4g/5g终端待机电流是多少?谁告诉您或者说您是经过什么测试后认为“一些后台app的网络流量对于基带维持信号的耗电相比可以忽略”?而且毒瘤软件在后台持续、频繁、反复联网还会导致系统无法正常休眠,这也是大量垃圾软件在后台联网间接导致的费电,所以只要让它们认为当前手机无网络自然就省电了。

更何况大部分人不可能拔sim,大家要接电话的。 这样说是否清楚?

最后我再说一遍,我一开始就说了我是根据自己的实测,提供一个思路:让APP认为系统无网络。我可没说让大家拔sim卡省电。您的理解能力是谁遗传给您的?

simplerick-simplefun commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

拔掉sim卡,或者直接在手机里面禁用sim,比如飞行模式,确实可以省电,但是这样就无法接打电话了。 保留电话信号的话,应用使用网络流量带来的耗电则是可以忽略的;主要是要限制唤醒和后台前台服务。

牛头不对马嘴的回复,能请您看完别人打的字再回吗?如果您不看就回,就请您不要再回了,您是把github issues当论坛闲聊板块了吗?

是你自己讲: 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。 我给你的回复是说你的这个思路在实际使用中没有用处。你拔了sim就不用让那些app认为无网络。你插上sim让那些app认为无网络也不省电,因为基带保持电话信号就是耗电的主体,而使用这个信号于一些后台app的网络流量对于基带维持信号的耗电相比可以忽略。更何况大部分人不可能拔sim,大家要接电话的。 这样说是否清楚?

谁告诉您基带待机很费电的?恢复出厂后4g待机就挺省电的,安装一大堆软件后待机就很费电,拔sim卡后待机特别省电,这还不能说明问题?您去看看运营商规定的4g/5g终端待机电流是多少?谁告诉您或者说您是经过什么测试后认为“一些后台app的网络流量对于基带维持信号的耗电相比可以忽略”?而且毒瘤软件在后台持续、频繁、反复联网还会导致系统无法正常休眠,这也是大量垃圾软件在后台联网间接导致的费电,所以只要让它们认为当前手机无网络自然就省电了。

更何况大部分人不可能拔sim,大家要接电话的。 这样说是否清楚?

最后我再说一遍,我一开始就说了我是根据自己的实测,提供一个思路:让APP认为系统无网络。我可没说让大家拔sim卡省电。您的理解能力是谁遗传给您的?

请不要把国内中文社区的抬杠文化搬到github。我一直都是在给出信息,尝试在帮助大家。 首先,就像几小时前countrysideboy提出的:

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

我怀疑就是基带耗电,因为实验机不插卡只开着wifi也挺省电。另外,理论上说,暂停了进程,应该对app来说网络活动也暂停,不走流量的

当我们通过各种方式,包括但不限于:thanox乖巧模式、冻结应用、绿色守护、thanox情景模式脚本等方式,减少、降低乃至停止了应用在后台的服务和唤醒,那么应用在后台就没有计算,没有cpu使用,也不会有网络开销。

其次,手机的基带耗电这件事,从10年前就有这方面的新闻和研究。具体的来讲,1.用户手机终端与信号塔基站越远、信号越弱,耗电越高。2.普遍的来讲,2G<3G<4G<5G。3.不同的信号频段的连接耗电也不同。4.不同的运营商的在手机和信号基站两边的配置、优化也影响耗电。5.不同的soc芯片,基带耗电也不同·。只能说,如果想要基带省电,可以根据自己的情况,自己调整设置3G/4G/5G。我前面最开始说的就是这个意思,限于手机回复,没说得很详细。根据我实际测试和网上的网友反馈,在信号强度都相对较好的情况下,5G换到4G、4G换到3G都是能有明显省电的。不推荐2G第一是因为2G下的SMS有安全缺陷,会被攻击,第二是因为现在2G几乎没有了。我之前没有说得很详细,还有一个原因是5G和4G分别有对应的VoNR和VoLTE,如果5G换到4G,或5G/4G换到3G,就会丢失这个功能,那就需要用户自己考虑自己的需求自己判断如何使用。

第三,一般手机休眠状态下,经过手机系统和用户手动设置的对于流氓软件的压制,后台的网络流量不会太多:一般都是微信这样的保持长连接,时不时发送几个小packet。这种情况下的应用网络流量,即便走的手机信号基带,也不会明显增大基带耗电。在这种情况下,主要的基带耗电在于维持手机信号,少许的网络流量的增加耗电与之相比可以忽略不计。如果是像手机网游那样一直传输数据,或者有应用在后台不断上传下载文件/数据,那么才会明显增大耗电。因此,你的情况不代表别人的情况。

第四,大部分人的使用场景是平时户外用流量,室内连wifi。而手机休眠大部分情况是室内。所以wifi下无需考虑应用后台流量走基带耗电。另一方面,既然在这个issue讨论,那么大家都是尽量限制应用的后台活动。你把活动限制住了,也就没有网络资源消耗了,也就没有基带耗电了。根据你的反馈,很有可能你手机上的应用在后台的活动比较多,网络资源使用比较多,超出了正常合理的(此处合理以google的推荐标准为准)活动量和网络使用量。那么正当的应对策略应该是限制这些应用的后台活动:把不必要的活动限制掉了,自然也就没有那么多网络使用,剩下的那一点push notification的流量还不至于有明显耗电。 另外,你说的情况,还有可能是你的手机后台应用不断地活动打扰了安卓正常的doze,使得手机没有使用时依然保持较高的cpu和ram的频率。这时如果把网络彻底关掉,有的应用是能够监测到网络关闭或网络连接失败的,那么这些应用就会暂停后台活动,等网络恢复再恢复后台。很多广告联盟模块和聚合推送模块都有乱七八糟的骚操作。尤其是聚合推送,你网络都没有了它自然就暂停了。 我建议你在手机上安装一个betterbatterystats,监测一下,就能看出来,是什么耗电的了。

最后,有什么想法,建议首先google搜索一下,自己研究一下。不要上来就开喷。github是用来分享知识合作建设的,不是用来抬杠的。然后,回复你最初的思路:“让APP认为系统无网络”没有实际操作价值。

Gokou-Ruri commented 1 year ago

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

不是那么简单。wifi环境下网络流量不走手机基带,也会有基带耗电。说白了就是手机维持一个电信信号就要耗电。手机离信号基站越近、接收的信号越强,耗电越少。耗电上5G>4G>3G。这方面我怀疑联发科的优化做得也没有高通好。

你看清我说的是拔sim和插sim对比,和WIFI一点关系都没有

拔掉sim卡,或者直接在手机里面禁用sim,比如飞行模式,确实可以省电,但是这样就无法接打电话了。 保留电话信号的话,应用使用网络流量带来的耗电则是可以忽略的;主要是要限制唤醒和后台前台服务。

牛头不对马嘴的回复,能请您看完别人打的字再回吗?如果您不看就回,就请您不要再回了,您是把github issues当论坛闲聊板块了吗?

是你自己讲: 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。 我给你的回复是说你的这个思路在实际使用中没有用处。你拔了sim就不用让那些app认为无网络。你插上sim让那些app认为无网络也不省电,因为基带保持电话信号就是耗电的主体,而使用这个信号于一些后台app的网络流量对于基带维持信号的耗电相比可以忽略。更何况大部分人不可能拔sim,大家要接电话的。 这样说是否清楚?

谁告诉您基带待机很费电的?恢复出厂后4g待机就挺省电的,安装一大堆软件后待机就很费电,拔sim卡后待机特别省电,这还不能说明问题?您去看看运营商规定的4g/5g终端待机电流是多少?谁告诉您或者说您是经过什么测试后认为“一些后台app的网络流量对于基带维持信号的耗电相比可以忽略”?而且毒瘤软件在后台持续、频繁、反复联网还会导致系统无法正常休眠,这也是大量垃圾软件在后台联网间接导致的费电,所以只要让它们认为当前手机无网络自然就省电了。

更何况大部分人不可能拔sim,大家要接电话的。 这样说是否清楚?

最后我再说一遍,我一开始就说了我是根据自己的实测,提供一个思路:让APP认为系统无网络。我可没说让大家拔sim卡省电。您的理解能力是谁遗传给您的?

请不要把国内中文社区的抬杠文化搬到github。我一直都是在给出信息,尝试在帮助大家。 首先,就像几小时前countrysideboy提出的:

我发现只要把sim卡拔了待机就特别省电,插卡(4g待机)就特别费电。 程序在后台费电不一定是因为吃CPU,也可能是因为网络传输导致基带费电,现如今基带耗电并不比CPU低多少,高速传输甚至比CPU还费电。 提供一个压后台思路:对某些网络依赖不太高的非IM软件可不可以让它们在待机时认为手机处于“无网络”状态?这样的话APP估计就不会频繁进行网络传输消耗电量了。

我怀疑就是基带耗电,因为实验机不插卡只开着wifi也挺省电。另外,理论上说,暂停了进程,应该对app来说网络活动也暂停,不走流量的

当我们通过各种方式,包括但不限于:thanox乖巧模式、冻结应用、绿色守护、thanox情景模式脚本等方式,减少、降低乃至停止了应用在后台的服务和唤醒,那么应用在后台就没有计算,没有cpu使用,也不会有网络开销。

其次,手机的基带耗电这件事,从10年前就有这方面的新闻和研究。具体的来讲,1.用户手机终端与信号塔基站越远、信号越弱,耗电越高。2.普遍的来讲,2G<3G<4G<5G。3.不同的信号频段的连接耗电也不同。4.不同的运营商的在手机和信号基站两边的配置、优化也影响耗电。5.不同的soc芯片,基带耗电也不同·。只能说,如果想要基带省电,可以根据自己的情况,自己调整设置3G/4G/5G。我前面最开始说的就是这个意思,限于手机回复,没说得很详细。根据我实际测试和网上的网友反馈,在信号强度都相对较好的情况下,5G换到4G、4G换到3G都是能有明显省电的。不推荐2G第一是因为2G下的SMS有安全缺陷,会被攻击,第二是因为现在2G几乎没有了。我之前没有说得很详细,还有一个原因是5G和4G分别有对应的VoNR和VoLTE,如果5G换到4G,或5G/4G换到3G,就会丢失这个功能,那就需要用户自己考虑自己的需求自己判断如何使用。

第三,一般手机休眠状态下,经过手机系统和用户手动设置的对于流氓软件的压制,后台的网络流量不会太多:一般都是微信这样的保持长连接,时不时发送几个小packet。这种情况下的应用网络流量,即便走的手机信号基带,也不会明显增大基带耗电。在这种情况下,主要的基带耗电在于维持手机信号,少许的网络流量的增加耗电与之相比可以忽略不计。如果是像手机网游那样一直传输数据,或者有应用在后台不断上传下载文件/数据,那么才会明显增大耗电。因此,你的情况不代表别人的情况。

第四,大部分人的使用场景是平时户外用流量,室内连wifi。而手机休眠大部分情况是室内。所以wifi下无需考虑应用后台流量走基带耗电。另一方面,既然在这个issue讨论,那么大家都是尽量限制应用的后台活动。你把活动限制住了,也就没有网络资源消耗了,也就没有基带耗电了。根据你的反馈,很有可能你手机上的应用在后台的活动比较多,网络资源使用比较多,超出了正常合理的(此处合理以google的推荐标准为准)活动量和网络使用量。那么正当的应对策略应该是限制这些应用的后台活动:把不必要的活动限制掉了,自然也就没有那么多网络使用,剩下的那一点push notification的流量还不至于有明显耗电。 另外,你说的情况,还有可能是你的手机后台应用不断地活动打扰了安卓正常的doze,使得手机没有使用时依然保持较高的cpu和ram的频率。这时如果把网络彻底关掉,有的应用是能够监测到网络关闭或网络连接失败的,那么这些应用就会暂停后台活动,等网络恢复再恢复后台。很多广告联盟模块和聚合推送模块都有乱七八糟的骚操作。尤其是聚合推送,你网络都没有了它自然就暂停了。 我建议你在手机上安装一个betterbatterystats,监测一下,就能看出来,是什么耗电的了。

最后,有什么想法,建议首先google搜索一下,自己研究一下。不要上来就开喷。github是用来分享知识合作建设的,不是用来抬杠的。然后,回复你最初的思路:“让APP认为系统无网络”没有实际操作价值。

github是用来分享知识合作建设的,不是用来抬杠的。

您可真行,您自己正在干的事不让别人干?

最后,有什么想法,建议首先google搜索一下,自己研究一下。不要上来就开喷。

凡事想当然然后反咬对方应该多Google多研究?

您上面这堆废话大部分与我的论点毫无关系,例如您反复扯3g/4g/5g网络切换这跟我的观点有任何关系吗?您是不是认为字多就能占理? Thanox要是能压得住后台APP耗电情况,您认为本issue为何存在? 在多人均反馈待机时APP后台联网导致耗电且有实测的情况下,您为何依旧想当然地固执己见认为APP只要服务和进程被限制,待机就能省电?您敢不敢拔sim卡待机试试?动嘴永远比动手容易。 连suspend和force-stop都压不住部分毒瘤软件更何况是您所谓的“限制服务和进程”?您就是Android之父? 请您倒回去看看您第一次回复我的那条评论,您当真认为您对其他用户给予了最起码的尊重认真看完对方的话再评论?搁那儿自说自话加戏我好心劝您认真看完再回,结果您马上又来个光速回帖并且再次做到了不看先回,先杠完再考虑其它?或者根本不考虑其它?

您的讨论于我、于其他用户有价值,我不至于屡次三番劝您认真看完再回我,我是最后一次请您不要再回复一些和我的观点毫无关系的内容了,也请您不要反咬。您第一次回我时的内容就非常莫名其妙,后面更是变本加厉,要说喷也是您在喷我。 无论结果如何我不会再参与和您的讨论,因为您在浪费我的时间。如果您认为自己的时间没有价值,您可以继续,但我不会再参与,您自便。