I am writing an Android application that does much of a processing in the background thread. The calculations are performed in the native code using C++. I want to update UI with the partial results during calculations.
I am able to do so through JNI, namely set reference to UI object in java and then call a method of this object from native code trough JNI. I am looking for a more efficient solution without any JNI calls in the rendering part (the basic setup and an activation entry point will have to be in java).
Is it possible to change execution thread from background to UI entirely in native code without using JNI (only in the rendering part)?
Thanks for your answers. Much appreciated.
EDIT:
I am considering using OpenGL to render calculated content (sort of video frames) in my view. In that case I would probably want to use eglSwapBuffers() method that is available in EGL library from 2.3 onwards. The biggest problem is, I think, how to easily switch from background "calculation" thread to UI "open GL" thread in native code without JNI overhead. What would you recommend? Thanks for your help!
PSEUDOCODE:
Here is some pseudocode that helps to illustrate what I want to achieve here. It is more like a threading issue but Android framework comes into play as well.
// background thread
void Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz)
{
//long calculation
struct result * res = calculate();
//want to update ui using opengl on ui thread
updateGL(res);
}
//want to run it on ui thread as opengl can be run only on ui thread
void updateGL(struct result * res)
{
//some opengl code with "res"
someGLcodeWithResult(res);
//render surface
eglSwapBuffers();
}
EDIT 2:
As the bounty slowly draws to close, one more clarification. There are couple of ways to call the updateGL method above. The most typical one is to use GLSurfaceView in java code. It would require setting a renderer (setRenderer()) and then overriding onDrawFrame with some code to call JNI/native layer. This way for every frame being rendered one JNI call gets executed.
I would like to do the rendering a little differently. I want to call updateGL without using java/JNI code at all and use only the native layer (as presented in the excerpt above). The biggest problem for me now is how to run the updateGL on UI thread (required by OpenGL) without the java callback. Is it at all feasible?
I suggest taking a look at the Mozilla Fennec source. There is a minimal Java/JNI shim that allows rendering on Android, but all the work is done via native code (regular ol' Mozilla code)
Great thoughts, but try and understand this thing
You have code in C++ in native
UI in java runs in VM
Now what you are asking is C++ code to interact with UI in Java VM which is another program to communicate. The only way to do it would be some interprocess communication. Having said that, now go figure that out which suits you best. JNI is fast and reliable, since u dont want to go that way, figure out any other IPC that suits you.
I'm facing the same problem right now. Perhaps this might help:
When you take a look at the STABLE-APIS.html in the latest NDK it says:
> V. Android-9 Stable Native APIs:
All the APIs listed below are available for developing native code that runs
on Android > 2.3 system images and above.
The EGL graphics library:
EGL provides a native platform interface to allocate and manage OpenGLES
surfaces. For more information about its features, please see:
http://www.khronos.org/egl
In a nutshell, this will allow you to do the following directly from
native code:
- List supported EGL configurations
- Allocate and release OpenGLES surfaces
- Swap/Flip surfaces for display (eglSwapBuffers)
So if you're targeting Android-9 then you could try to use the EGL lib in native code.
(Let me know if this works :))
Is it possible to change execution thread from background to UI entirely in native code without using JNI?
You cannot modify widgets from native code.
Related
I'm building an audio / music app. in Android. And because of this I'm using the new Oboe C++ library.
I'm wondering how people do graphics and UI in Android with NDK applications.
I don't think I need OpenGL or a low level, fast graphics library. This isn't a game. I really just need to pick up different touches in different locations / from some custom UI widgets. (But I do need multitouch).
Is there a convenient highish-level API for doing the drawing and picking up touches from C++? If so, what is it? Or would I be better doing all the UI in Java and just calling down to the NDK for the audio?
This is the first time I'm trying to work with Android NDK and the Oboe examples I've looked at don't really draw anything in C++. The one "hello world" example, uses Java widgets. And the others don't really draw anything on the screen at all.
To be clear, Multitouch events are handled and made available by the Java/Kotlin side of the Android Framework so you would need to pass those down through the JNI level. A reason to draw at the NDK layer is to reduce the latency of passing a result back up through the JNI layer to the Java/Kotlin layer which would have to update any widget/view.
two years ago i developed an Augmented Reality framework on android-7 (Eclair). Since AR application are computationally intensive task, I developed a JNI c++ library used by a Java activity to render and register the virtual environment. The sensor readings acquired in Java are passed to the underline c++ library to compute the registration of the virtual environment. Tridimensional objects are rendered by a native draw function called from a GLSurfaceView. This results in a lot of JNI call.
Now I would like to port the application to android-15(Ice Cream Sandwich). Starting from android-9(Gingerbread) Android allows to use NativeActivity.
I would like to understand which is the better way to develop an AR application. Since every JNI calls introduce an overhead it would be much better to avoid them. Is it possible using NativeActivity? I didn't find an exaustive guide that explains how NativeActivity works but reading this document it seems that it results in a lot of JNI calls anyway. Is there any architectural document that explains how NativeActivity works? Is NativeActivity just a "JNI wrapper" to avoid java code? Concerning performances,are there any advantages using NativeActivity instead of a JNI library as I done before?
Thanks a lot.
NativeActivity will not give a performance boost to your framework. It still uses JNI to communicate with the System, only under the cover.
Moreover, there are good reasons not to use it. If I understand your purpose correctly, you want other applications to take advantage of your code. By forcing them to use NativeActivity you seriously reduce their freedom, and require that they struggle with a less familiar environment. There is a number of limitations with NativeActivity, e.g. it cannot load more than one JNI library.
Finally, I would suggest a completely different direction if you look for optimization of your AR framework: you can use the new setPreviewTexture() API.
As far as I understand it you still are bound to JNI also when using NativeActivity. This class can be used as starting point and encapsulates some functionalities for your convenience but the underlying technology to access native code has not changed and ist still JNI. So in my opinion you only can do some benchmarks to check if NativeActivity is more efficient for some reason (may be the guys at Google do know some hacks that make it faster than your solution).
i have develop one game size of 27mb,i load it in device & its performance are going to lower and some time its hang the device.there are much Media resource are used in this game.if i make it in android then i will handle with Asynctask and make some process in background and also make memory management but here i have develop game in flash with AS3 and use Adobe Air. so my question is :: is there any method like asynTask are stay in flash or any performance related thing by which i take precaution against poor performance?
Thanks
nik
You should consider using Flash 11 and AIR 3 - the new version allow the execution of native code, so that you can use Flash and AIR for the UI and the animations while at the same time you can execute asynchronously some native threaded code that otherwise would have of been occupying the time in between frames. In the native code you can have all of the calculations that are not related to the UI - e.g. the AI logic.
A detailed tutorial is provided by Lee Brimelow on his blog - Two-Part Tutorial on Android Native Extensions
As far as I know there's only two threads network thread and thread doing all other actions.
Asynctask is about optimal using UI thread, so because of there's no separate UI thread in flash/AIR there could be no analogous tricks. As for other methods, I'm affraid there's no general answer.
If you want to load assets asynchronously, you should use the URLLoader and Loader classes to load resources. They will load stuff in the background and throw an Event (Event.COMPLETE) when they are done.
Here are some links on how to use PixelBender to do stuff like number crunching in a separate thread, I'm not sure it is supported on Android though, so you would have to look in to that further:
http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html
Stack Overflow question, the answer by Ascension Systems:
Flash parallel programming
You should read Optmizing performance for the Flash Platform
help.adobe.com/en_US/as3/mobile/flashplatform_optimizing_content.pdf
Not really an immediate source code question per se....but Im looking into doing some casual Android Programming, nothing heavy.
But it seems to use alot of XML and Java......what I wonder though is why is it that android is written mostly in C and XML (along with C++ and Java) with it being closely related to the Linux OS......but why is the "main" language for programming in android Java?
Just out of curiosity of course.
The "main" language, as you called it, is Java. You can use C/C++ via the NDK, but you won't need it unless you are doing some special stuff. If you wonder when you would need to use C/C++, take a look at the official documentation:
When to Develop in Native Code
The NDK will not benefit most applications. As a developer, you need to balance its benefits against its drawbacks; notably, using native code does not result in an automatic performance increase, but always increases application complexity. In general, you should only use native code if it is essential to your application, not just because you prefer to program in C/C++.
Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on. Simply re-coding a method to run in C usually does not result in a large performance increase. When examining whether or not you should develop in native code, think about your requirements and see if the Android framework APIs provide the functionality that you need. The NDK can, however, can be an effective way to reuse a large corpus of existing C/C++ code.
The Android framework provides two ways to use native code:
Write your application using the Android framework and use JNI to access the APIs provided by the Android NDK. This technique allows you to take advantage of the convenience of the Android framework, but still allows you to write native code when necessary. You can install applications that use native code through the JNI on devices that run Android 1.5 or later.
Write a native activity, which allows you to implement the lifecycle callbacks in native code. The Android SDK provides the NativeActivity class, which is a convenience class that notifies your native code of any activity lifecycle callbacks (onCreate(), onPause(), onResume(), etc). You can implement the callbacks in your native code to handle these events when they occur. Applications that use native activities must be run on Android 2.3 (API Level 9) or
You cannot access features such as Services and Content Providers natively, so if you want to use them or any other framework API, you can still write JNI code to do so.
I am just guessing but Java is a bit easier to program than C/C++ so its more attractive to new programmer which is also good for the platform success itself.
Another reason might be that an application written in java runs in a separate VM so it can be much easier controlled by android. If a vm is not responding the main OS can just kill it and the phone is still responding.
Suaron... From a stability point of view Java apps should be less likely to take down the device. So Java || C# || C++/CLI safer than C++ vs C vs Assembly. To this end the API is in Java and so most Apps are in Java.
On the other hand C/C++ gets closer to the hardware and is more appropriate for writing libraries that interact with hardware. It is much easier to shoot yourself in the foot with C++.
JAL
The Android NDK has just been significantly expanded to include support for writing android applications entirely in native C/C++ code. One can now capture input events on the keyboard and touch screen using native code, and also implement the application lifecycle in C/C++ using the new NativeActivity class.
Given all the expanded native capabilities, would it be worthwhile to completely bypass Java and write Android application in native code?
The NDK is not native per-se. It is to a large extent a JNI wrapper around the Android SDK. Using NativeActivity gives you a convenient way of dealing with certain app-life cycle events, and add your own native code on top. ALooper, AInputQueue etc. are all JNI wrappers of the Java SDK counterparts, some with additional code that is private and unaccessible for real apps.
When it comes to Android development, there's no such thing as writing an application entirely in native C++ - you will (in every real App case that I can think of) always need to use the Android API:s, which are to a huge extent pure Java. Wether you use these through wrappers provided by the NDK or wrappers that you create yourself doesn't really change this.
So, to answer your question: No, it wouldn't be worthwhile, because you would end up writing JNI wrappers for SDK calls instead of writing JNI wrappers to your own Java methods that do the same thing, with less code, simpler code and faster code. For example, showing a dialog using "pure c++", involves quite many JNI calls. Just calling a Java method through JNI that does the same thing will give you faster code (one JNI call), and, arguably, code that is easier to maintain.
To fully understand what you can do, you really must examine the Android source code. Start with native_app_glue.c, which is available in the NDK, then continue with the OS implementation of AActivity, ALooper, AInputQueue etc. Google Code Search is a great help in this. :-)
If it is easy to do in Java, and includes many calls, call a method through JNI that does it all, rather than writing all the extra code to do it with multiple JNI calls. Preserve as much of your existing C++ code as is reasonable.
Not if you are just making a standard application. The Java SDK is more complete than its Native counterpart right now so you would still be making things more difficult for yourself.
If you are not doing something that requires the NDK (read: real time performance sensitive) then stick with Java.
Just some food for thought but if you have an app on iOS and Android, some C/C++ code might be shareable. Obviously the iOS Obj-C and platform specific code wouldn't work elsewhere. (Ditto for the Android specific stuff). But you might be able have some shared code that's platform neutral.
If you can, stick with the java style apps until versions of Android supporting native activities constitute a significant fraction of the installed base.
For things that were hard to do before - particularly ports of existing code - this will probably be a big help.
It's not entirely clear yet what has changed vs. just writing your own thin java wrapper. For example, is there still a copy of the dalvik VM hanging around?