Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "exec()" with NDK

Tags:

android-ndk

I remember reading somewhere that it isn't advisable to use "exec" within the C code, compiled by NDK.

What is the recommended approach? Do we try and push the EXEC code up to the Java-space; that is, so the JNI (or application) spawns the new process, (and where relevant passes the results back down to the NDK)?

like image 222
jayfred Avatar asked Dec 20 '22 06:12

jayfred


1 Answers

First off, it's not recommended to use either fork or exec. All of your code is generally supposed to live in a single process which is your main Android application process, managed by the Android framework. Any other process is liable to get killed off by the system at any time (though in practice that doesn't happen in present Android versions as far as I have seen).

The rationale as I understand it is simply that the Android frameworks can't properly manage the lifetime and lifecycle of your app, if you go to spawn other processes.

Exec

You have no real alternative here but to avoid launching other executables at all. That means you need to turn your executable code into a library which you link directly into your application and call using normal NDK function calls, triggered by JNI from the Java code.

Fork

Is more difficult. If you really need a multi-process model, and want to fit within the letter of the rules, you need to arrange for the Android framework to fork you from its Zygote process. To do this, you should run all your background code in a different Service which is stated to run in a different process within the AndroidManifest.xml.

To take this to extremes, if you need multiple identical instances of the code running in different processes for memory protection and isolation reasons, you can do what Android Chrome does:

  • Run all your background/forked code in a subclass of Service
  • Create multiple subclasses of that
  • List each of these subclasses as a separate service within your AndroidManifest.xml each with a different process attribute
  • In your main code, remember exactly which services you've fired up and not, and manage them using startService/stopService.

Of course, if you've turned your native code into a library rather than an executable, you probably don't need fork anyway. The only remaining reason to use fork is to achieve memory protection/isolation.

In practice

In practice quite a lot of apps ignore all this and use fork/exec within their native code directly. At the moment, it works, at least for short-running tasks.

like image 85
Adrian Taylor Avatar answered Apr 19 '23 22:04

Adrian Taylor