I am processing UI instructions on a virtual machine (V8 actually) on Android in the main UI thread. This works fine. However, now I'm adding a JavaScript debugger into the mix (Stetho in my case). I can pause the UI thread when a breakpoint is hit, and even step through instructions. However, when an instruction changes the UI, the UI is not immediately updated. Instead, the view is invalidated and only when the main event loop continues processing will the updates render.
So my question is, can I force a redraw of the entire device from the UI thread without returning to the main loop? If I return to the main loop then I will blow my entire call stack, and pausing during debugging will no longer work.
I tried to get the main Looper, and I can even call Loop() on it (ideally to start processing the events), but then this will become the main loop (and you cannot quit the main looper). If anyone has any thoughts on how to simulate the main event loop, that would be greatly appreciated.
This is fun, I'm doing the same thing as you, creating a bridge between J2V8 and Stetho. The trick is to run the debugger in it's own thread. Since the debugger will have direct access to V8, it can easily manipulate the runtime, but commands going to Native code (like UI commands) will run on the main thread until they come back to the V8 runtime.
Related
I excuse for asking a quite vague question, but, I have a pure native NDK application which is supposed to execute in Immersive Mode (i.e fullscreen).
The immersive mode JNI snippet is executed when the app is resumed via APP_CMD_RESUME. This works most of the time, but, every now and then the command activity->vm->DetachCurrentThread() in my SetImmersiveMode() snippet crashes with a fatal exception:
FATAL EXCEPTION: Thread-10
Process: com.toppluva.portis.LocalDebug, PID: 5474
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7380)
at android.view.ViewRootImpl.recomputeViewAttributes(ViewRootImpl.java:3478)
at android.view.View.setSystemUiVisibility(View.java:22587)
This really boggles me, mainly because it happens every now and then, how can I detect if I'm executing from this original thread?
Note that according to the documentation APP_CMD_RESUME executes from main thread.
View.setSystemUiVisibility() should be called from the main thread only. Without seeing your code, it's hard to tell if DetachCurrentThread() plays any role in this.
documentation, ANativeActivity::env is JNI context for the main thread of the app.
You should call DetachCurrentThread() before terminating a native thread that you attached to JVM.
You should not call DetachCurrentThread) on a thread born in Java, e.g. the UI thread.
Note that you may call AttachCurrentThread() at any time and on any thread. It will be equivalent to NOP on a Java thread or on an attached thread.
These attach/detach are not paired like parentheses. Any number of attach calls is reversed by single detach. The recommended practice:
use pthread_key_create to define a destructor function that will be called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
See how WebRTC handles attach/detach in their git Web repo.
i know that the android app runs in the main thread means UI thread.I want to know what is need of main thread to run an app? What happens if we do not use the main thread to run app.Why main thread is necessary?
Well it needs a thread. Every app ever written has at least one- even the simplest Hello World app in the simplest language. A thread is just a series of instructions being run on the processor. So even if your app doesn't multithread at all, the one series of instructions it is running would be a thread- you could even call it the main thread if you wanted. So it would literally be impossible to have no main thread at all.
What makes the main thread special in Android is that you're only allowed to change visible elements on it. If Android didn't have that restriction, you'd have the possibility of race conditions and inconsistent UIs- the possibility that views are being changed on one thread while another is drawing to the screen. To prevent this you'd need to do a lot of manual locking. Instead, Android decided to only allow these changes on the main thread. That prevents a large class of timing bugs and race conditions (although not all, depending on how you implement your models).
From this link:
What is the need of main thread?
When an Android application is first started, the runtime system creates a single thread in which all application components will run by default. This thread is generally referred to as the main thread. The primary role of the main thread is to handle the user interface in terms of event handling and interaction with views in the user interface. Any additional components that are started within the application will, by default, also run on the main thread.
Why is main thread necessary?
Any component within an application that performs a time-consuming task using the main thread will cause the entire application to appear to lock up until the task is completed. This will typically result in the operating system displaying an “Application is unresponsive” warning to the user. Clearly, this is far from the desired behavior for any application. In such a situation, this can be avoided simply by launching the task to be performed in a separate thread, allowing the main thread to continue unhindered with other tasks.
Please refer to the link to understand more about main thread with an example.
For more details, you can follow this link.
How do I check why an application is running slow? More precisely, which lifecycle method is taking more time to execute in Android.
I have already tried logging the lifecycle methods of each activity and fragment, but I could not figure out the reason for the delay.
The onCreate is called, but then there is quite a delay (around 1s) before onResume is called.
Owing to the above delay, the user feels like the application is not very responsive.
The delay is reduced to about 100ms for high end phones. But it the old 2012-2011 models that have this huge delay.
A few ideas on how to investigate further into identifying the root cause of delays, and how could we optimise apps to navigate through screens faster.
Thanks in advance.
If you are processing heavy load of data (including complex UI rendering) in main thread , then you can find this kind of message in logcat:
W/Trace(1274): Unexpected value from nativeGetEnabledTags: 0
I/Choreographer(1274): Skipped 55 frames! The application may be doing too much work on its main thread.
This may cause your application to slow down with respect to rendering
UI
Suggestable Fix
Fixing this requires identifying nodes where there is or possibly can happen long duration of processing. The best way is to do all the processing no matter how small or big in a thread separate from main UI thread. So be it accessing data form SQLite Database or doing some hardcore maths or simply sorting an array – Do it in a different thread
Now there is a catch here, You will create a new Thread for doing these operations and when you run your application, it will crash saying “Only the original thread that created a view hierarchy can touch its views“. You need to know this fact that UI in android can be changed by the main thread or the UI thread only. Any other thread which attempts to do so, fails and crashes with this error. What you need to do is create a new Runnable inside runOnUiThread and inside this runnable you should do all the operations involving the UI. Find an example here.
So we have Thread and Runnable for processing data out of main Thread, what else? There is AsyncTask in android which enables doing long time processes on the UI thread. This is the most useful when you applications are data driven or web api driven or use complex UI’s like those build using Canvas. The power of AsyncTask is that is allows doing things in background and once you are done doing the processing, you can simply do the required actions on UI without causing any lagging effect. This is possible because the AsyncTask derives itself from Activity’s UI thread – all the operations you do on UI via AsyncTask are done is a different thread from the main UI thread, No hindrance to user interaction.
So this is what you need to know for making smooth android applications and as far I know every beginner gets this message on his console.
I am using libDispatch (GCD) opensource on Android platform.
So, most of the complex time consuming tasks are being done through NDK (where i am using libDispatch).
For some calls, I am using dispatch_async(get_main_queue)...This is where the problem is coming...
I am able to run tasks in the concurrent queues but not on main queue.
Since this requires dispatch_main() to be called which we cannot do on here as Java thread will be blocked in that case.
So, is it possible to run the Java UI on some secondary thread and hook the dispatch_main() to serve the dispatch_main_queue here?
OR : Do I need to keep serving the main_queue from JAva main UI thread through JNI ?
Look into _dispatch_main_queue_callback_4CF which is the function you can call to drain the main queue. It will return like a normal sensible function after executing the queued operations, instead of killing the thread like dispatch_main.
Note that you'll need to call _dispatch_main_queue_callback_4CF on a regular basis from your Java UI thread, possibly each iteration. The official Cocoa implementation uses _dispatch_queue_wakeup_main() which uses mach messages to kick the main thread out of any sleep states so it can guarantee the callback function is called quickly, but you'd have to do some work to enable that and build your own libDispatch port. In reality on Android I don't think the main UI thread is ever put to sleep while your app is active so it shouldn't be an issue.
There is a ticket open on the libDispatch site at https://libdispatch.macosforge.org/trac/ticket/38 to make _dispatch_main_queue_callback_4CF a public function. The ticket is marked "Accepted" but no word on if/when that will happen.
The Android doc says "Like activities and the other components, services run in the main thread of the application process."
Is the main thread here the same thing as UI thread?
Looks like it. Quoted from http://android-developers.blogspot.com/2009/05/painless-threading.html: "When an application is launched, the system creates a thread called "main" for the application. The main thread, also called the UI thread...", Official API document.
UI Thread and Main Thread are same only in Android.
The Main thread, that is responsible for handling the UI events like Draw, Listen and receive the UI events.
Ans also it is responsible for interact with running components of the UI toolkit for the corresponding application that belongs to.
When an User event occurs in the application, the Main thread *
need to add the event in the queue -> intimate about the event to
appropriate View -> change the state of the view -> redraw the view
according to the state changes -> waiting for the response for the
particular event action -> after intimated and event action completed
need to delete the event in the queue.
*
The above every actions are handled by the Main thread (Not only the above operation, it is a one of the operation handled by the UI Thread), So if our application fails to respond the event about 5 seconds android will shows the error "not responding".
So only it is widely suggested to do the light processes in the UI thread.
Hope this answer is somewhat detail and helpful to the new android bees like me.
I just shared what i learned about UI Thread. If i went wrong in anywhere please don't hesitate to recorrect me.
Basically Main Thread is Ui Thread.
However sometimes they can be different treads!
It is possible for system apps with multiple views on different threads.
Also if you use support annotations note that both #MainThread and #UiThread are available at the same time.
Here with the first one you annotate methods associated with the App life cycle and with the second one methods that are in charge of view hierarchy.
https://developer.android.com/studio/write/annotations.html
The "main application thread" is sometimes called the "UI thread".
Every Activity has its own UI thread.
As soon as the VM boots up, System Server is started by the Zygote. All other services like Activity Manager Service are started in new threads by the System Server.
Yes. main thread is UI thread.
See this tutorial for full details about background processing in android