Killing long native code on Android
How can I immediately drop a long running computation in native (C) code on Android when the user clicks the Cancel button without inserting undo checks?
To explain the limitations:
- This native code is too complex to insert enough undo checks or progress information [1], so the process must be forcibly killed.
- The user interface of the Android application must remain enabled (hence a separate process) so that the user can easily iterate over the various options.
- There is no need to support more than one such computation at a time.
I'm well aware that the general position on the process lifecycle on Android is that you should let the platform manage it for you. However, I want to get as close as possible to the above requirement with as many unsupported operations as possible.
I have a solution below, but I hope it gets better there. For example, if you split the service into an additional process using the android: process attribute on <service>
, and a single thread that enters a deep JNI call, is there a way to immediately kill such a process or exit without causing the runtime to treat it as an unexpected failure?
[1] I have tried canceling checks. That's over 70,000 SLOC (3.1 MB) C, whose memory allocations and control flow are complex; it was not written with interruption in mind. Thus, double error free()
and unused failures on subsequent work.
source to share
Here's what I'm doing now:
- In build.gradle : compile the native language-only executable as if to invoke the command line.
- The magic words for finding other people are doing this ndk "BUILD_EXECUTABLE" .
- This name should be named as if it were a library to convince the build tools to include it and the package installer on devices to unpack it.
- This is not yet achievable in Android Studio NDK support , and I really hope the final release leaves that door open in some roundabout way.
- When the process starts , copy it to the path where I can
chmod +x
, do that andRuntime.exec()
it (I only need <1KB from stdout). - To stop the process, just type
.destroy()
on it.
The validity of this question is questionable: the NDK docs say how you can create an executable, but it will not be installed . Empirically, however, it has broad compatibility with major Android devices since at least v2.1-5.1. It is deployed in a widely used application (100,000 downloads, ~ 47,000 active).
Environments where this fails, probably during shenanigans binary installation, include:
source to share