当用户按下“取消”按钮时,我如何在不插入取消检查的情况下立即放弃 Android 原生代码(C 语言)中长时间运行的计算?
解释约束:
- 此 native 代码太复杂,无法插入足够的取消检查或进度信息[1],因此必须强行终止该进程。
- Android 应用的用户界面必须保持运行(因此是一个单独的进程),以便用户方便地使用不同的参数重试。
- 一次不需要支持多个这样的计算。
我很清楚 Android 上进程生命周期的一般立场是您必须让平台为您管理它。尽管如此,我希望通过尽可能少的不受支持的操作来尽可能接近上述要求。
我在下面有一个解决方案,但我希望有更好的解决方案。例如,如果您使用 android:process attribute 将服务拆分为一个额外的进程在 <service>
上,并且其中一个线程进入深度 JNI 调用,有没有一种方法可以立即终止这样的进程,或者从内部退出它,而不会导致运行时将其视为意外崩溃?
[1] 我尝试过取消检查。它有超过 70,000 个 SLOC(3.1 MB)的 C,其内存分配和控制流很复杂;编写它时并没有考虑到可中断性。那条路是双free()
以及后续操作中莫名其妙的崩溃。
最佳答案
这是我目前所做的:
- 在build.gradle :编译一个仅限 native 的可执行文件,就像命令行调用一样。
- 搜索其他执行此操作的人的魔法词是 ndk "BUILD_EXECUTABLE" .
- 这必须像库一样命名,以说服构建工具包含它并说服设备上的包安装程序解压缩它。
- 这在 Android Studio Preview NDK support 中还无法实现我真的希望最终版本能以某种迂回的方式打开这扇门。
- 何时starting the process ,将它复制到我可以
chmod +x
的路径,执行该操作,然后Runtime.exec()
它(我只需要来自标准输出的 <1KB)。< - 要停止进程,只需对其调用
.destroy()
。
对此的支持值得怀疑:NDK 文档讨论如何 you can build an executable but it won't get installed .不过,根据经验,它与至少 v2.1-5.1 之间的主流 Android 设备具有广泛的兼容性。它部署在 widely-used app 中(100,000 次下载,约 47,000 次活跃)。
失败的环境,可能是在上面的二进制安装恶作剧期间,包括:
关于android - 杀死 Android 上长时间运行的 native 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31440067/