Must a ProgessDialog run in an AsyncTask or on a seperate Thread? - android-asynctask

I have two activities. The second activity if for data collection from the user (he types in new data) and the first for showing graphs. Once the user finish the second activity (by clicking back), I need to do calculations before the charts update on the MainActivity. It is important that the calculations finish first before activity 2 is finished. The code therefore runs in the onBackPressed method.
There seemed to be three options:
1) Use a thread that does the calculations and update the ProgressDialog with a seperate handler to watch for thread completion. The handler receives a message once the thread is complete and then close the second activity. Android Studio warns me that the handler needs to be static and warns me of memory leaks. So this doesn't seem to be a safe approach.
2) Use an AsyncTask and wait until the AsyncTask is completed before closing activity two. However, it appears meaningless to run a seperate thread or an AsyncTask for calculations that should run on the main thread simply to show a ProgressDialog.
3) Show the ProgressDialog on the main thread. However, this does not seem to be possible.
Could you please point this noob to the right method to show a ProgressDialog while sequentially executing calculations for which the user must wait (only a few seconds).
Thanks,
Jean

Use the AsyncTask in Activity one there is no need to open second activity for load data and calculation you can do that in activity one and just use progress dialog in AsyncTask and close that dailog in postExecute method of Asynctask and Call that AsyncTask on OnCreate() method of Activity One.

Related

Nativescript - ActivityIndicator not working for a specific chunk of code

I'd like to display an activity-indicator displayed when I do a long process.
I set a model busy flag to true.
I then call a method that returns a Promise - when the promise calls resolve, I then set the busy flag to false in my 'then' handler.
When I wait for the promise to resolve, I expect the Activity Indicator animation to be displayed but it's not.
I checked and made sure the UI set up is correct and it works.
The work that's being done is using nativescript-calendar plugin - I'm adding a few calendar entries.
I commented out the work that's being done and just went to sleep for a little bit and then called resolve() and the animation worked.
So the Activity Indicator and the Promise mechanism is setup correctly - it's something this plug-in is doing that's causing the AI not to display.
What could cause such a behavior?
I actually edited the Promise work code - put to sleep for about 1 second and then started the calendar work. I see the AI for 1 second and then it freezes.
So it looks like the calendar writes is causing the AI to freeze.
I was under the understanding that Promise work is done in the background and should not effect foreground animation.
I've had a similar issue when using SQLite.
As you haven't explicitly stated that your running the calendar in a worker I am assuming your keeping it in the UI thread (main thread).
Any large amount of work done in the UI thread will cause noticeable lag/delays. So for example you call the activity-indicator then call a process that maxes out the thread, the process finishes the activity indicator goes to be drawn on the screen but then is hidden straight away before it is displayed as the process is finished.
The ideal way to solve this is to move the calendar writes code into a worker (multithread your app) and on success message turn off the activity-indicator.

CFRunLoopObserver vs. nested CFRunLoops

I`ve got a Cocoa UI app that needs to update its main window as fast as the rest of its UI event loop permits, so I implemented the main updater function via a CFRunLoopObserver. I also have an application-modal alert box and a context menu.
So, my problem is that when I have both an alert and a context menu on the screen, the updater gets stuck, presumably due to excess number of nested run loops above the one it has been attached to back at the start. Surprisingly, I can alleviate the issue by duplicating the observer, and it keeps running — one instance only, randomly chosen from the two existing when the «blocking» nested loop starts. When it ends (a menu item gets chosen, an alert exceeds its timeout or is dismissed manually — whatever), things get back to normal, and the blocked observer regains the ability to run.
Now the question: is there a way to have a single observer that gets executed no matter how deep the run loop stack is?
Sidestepping the runloop issue, have you looked at CVDisplayLink?
You set one up using CVDisplayLinkCreateWithActiveCGDisplays(), and then attach a callback using CVDisplayLinkSetOutputCallback(). It'll ask for data at the refresh rate of the display, so you'll be getting the callback as fast as you need.

How modal dialog is implemented?

For a long time I have been wondering how modal dialog is implemented.
Let me take Qt as an example. (Nearly all GUI toolkit has this mechanism)
In the main event loop, a slot is called, and in this slot a modal dialog is opened. Before the dialog is closed, the slot doesn't return control to the main event loop. So I thought that the main event loop is blocked and become unresponsive. Apparently this is not true, since when you open a modal dialog, the background main window is still working, like repainting its UI or keep displaying a curve or some graph. It just becomes not to accept any user input.
I did an experiment. I didn't open a modal dialog in the slot, but start a new thread there, and wait for the thread to finish in that slot. This definitely blocked the main event loop.
How modal dialog is implemented after all? How does it keep main event loop unblocked but at the same time blocked the calling slot?
There is only ever a need for a single event loop, and it does not block when a modal dialog appears. Though, I suppose, different toolkits may handle this differently. You would need to consult the documentation to know for sure. Conceptually, however, it all works in the same way.
Every event has a source where the event occured. When a modal dialog appears, the event loop either ignores or redirects all events that originate outside of the dialog. There's really no magic to it. Generally speaking, it's like an if statement in the event loop code that says "if (modal_is_shown() and !event_is_in_modal_window()) {ignore_and_wait_for_next_event()}". Of course, the logic is a bit more complicated, but that's the gist of it.
If you're looking for examples here's another one:
In Tk, there is only ever one event loop. Modal behavior (doesn't have to be dialog, can also be tooltips, textbox etc) is simply implemented by making the main window ignore mouse and keyboard events. All other events like redraws etc. can still be serviced because the event loop is still running.
Tk implements this via the [grab] function. Calling grab on a UI object makes it the only object able to respond to keyboard and mouse events. Essentially blocking all other objects. This doesn't mess with the event loop. It merely temporarily disables event handlers until the grab is released.
It should be noted that Unix-like operating systems running X also has grab built in to the windowing system. So it's not necessarily implemented merely by UI toolkit libraries but is sometimes also a built in feature of the OS. Again, this is implemented by simple blocking/disabling of events instead of instantiating separate event loops. I believe this also used to be the case for the older MacOS before OSX. Not sure about OSX or Windows though. Even though modality is often implemented by the OS itself, toolkits like Qt and Tk often implement their own mechanisms to standardize behaviors across different platforms.
So the conclusion is, it is not necessary to block the main event loop to implement modality. You just need to block the events and/or event handlers.
The answer by https://stackoverflow.com/users/893/greg-hewgill is correct.
However, reading the follow-up discussion between him and https://stackoverflow.com/users/188326/solotim , I feel that there is room for further clarification, by means of prose and some pseudo-code.
I'll handle the prose part with a fact-list:
The main message loop does not run until the modal activity is finished
However, events are still delivered while the modal activity is running
This is because there is a nested event loop within the modal activity.
So far I just repeated Greg's answer, please bear with me as it is for continuity's sake. Below is where I hope to contribute additional, useful info.
The nested event loop is part of the GUI toolkit, and as such, it knows the callback functions related to every window in existence
When the nested event loop raises an event (such as a repaint event directed to the main window), it invokes the callback function associated with that event. Note that "callback" here may refer to a method of a class representing a window, in object-oriented systems.
the callback function does what is needed (e.g., repaint), and returns right back to the nested message loop (the one within the modal activity)
Last, but not least, here's pseudo-code to hopefully illustrate further, using a fictitious "GuiToolkit":
void GuiToolkit::RunModal( ModalWindow *m )
{
// main event loop
while( !GuiToolkit::IsFinished() && m->IsOpen() )
{
GuiToolkit::ProcessEvent(); // this will call
// MainWindow::OnRepaint
// as needed, via the virtual
// method of the base class
// NonModalWindow::OnRepaint
}
}
class AboutDialog: public ModalWindow
{
}
class MainWindow: public NonModalWindow
{
virtual void OnRepaint()
{
...
}
virtual void OnAboutBox()
{
AboutDialog about;
GuiToolkit::RunModal(&about); // blocks here!!
}
}
main()
{
MainWindow window;
GuiToolkit::Register( &window ) // GuiToolkit knows how to
// invoke methods of window
// main event loop
while( !GuiToolkit::IsFinished() )
{
GuiToolkit::ProcessEvent(); // this will call
// MainWindow::OnAboutBox
// at some point
}
}
In general, a modal dialog box of this type is implemented by running its own message loop instead of your application's message loop. Messages directed to your main window (such as timer or paint messages) will still get delivered, even during the modal operation.
In some situations, you may have to be careful that you don't recursively do the same thing repeatedly. For example, if you trigger a modal dialog box on a timer message combined with some persistent flag, you'll want to make sure you don't keep bringing up the same dialog box repeatedly whenever the timer message fires.

DispatcherTimer not updating with AdControl running

I have a simple app that I am creating with a countdown timer that uses a DispatcherTimer for the time base. I have an event handler setup for On_Tick of the DispatcherTimer (set for 1 sec interval). I have three (3) pivot pages using three different instances of AdControl and all are "live" with a real ApplicationID and AdUnitID. This timer is setup on one of the pivot pages.
What I am seeing is that when I open my app and the AdControl starts, after 60 seconds, the adControl wants to refresh. My timer works fine for the first minute, then starts to lose a second every three seconds, like it is missing a tick event (coincidentally when the adcontrol "scrolls" to a new message every three seconds?). I've tried using a background worker for the dispatcherTimer but that did not seem to do anything for me. The code in the event handler is fairly short, with just a couple of "if-then" statements and a few textBlock updates.
Anyone else seen similar issues with the AdControl?
I would say the reason is that the ad control and the timer both want to do something on the UI thread. Thus when the ad control is busy the timer action is blocked during this time. To quote MSDN:
Timers are not guaranteed to execute exactly when the time interval
occurs, but they are guaranteed to not execute before the time
interval occurs. This is because DispatcherTimer operations are placed
on the Dispatcher queue like other operations. When the
DispatcherTimer operation executes is dependent on the other jobs in
the queue and their priorities.
It also explains why using a background worker does not help. As soon as you go back from another thread to the UI thread you have the same problem again. So this issue is basically by design.
Oh and it can also be the other way round. If you would be doing intensive work in the UI thread then the ad control would be blocked. As well as the rest of your UI. This is the reason why you should do as much work as possible in background threads. Maybe the ad control doesn't adhere to this advice.
So far this probably won't help you much. But perhaps it is possible to just use one AdControl and move this from Pivot to Pivot as the user pans around?
I've experienced the same problem with my own timer style app. In my case it only appears to happen when there is animation in the current advertisement.
According to the DispatcherTimer documentation, the delay is expected behaviour, so the solution it to use a different timer... eg System.Threading.Timer
...
//create the timer
var timer = new System.Threading.Timer(
new System.Threading.TimerCallback(TimerTick),
null,
//Set the due time to infinite so the timer wont start immediately
System.Threading.Timeout.Infinite,
0);
//start the timer
timer.Change(0, 1000);
//stop the timer
timer.Change(System.Threading.Timeout.Infinite, 0);
}
void TimerTick(object state)
{
//Dont forget to update the UI on the UI thread.
Dispatcher.BeginInvoke(() =>
{
MyTextBox.Text = "New Text";
});
}
Problem solved!

"Independent" GUI window launching

I'm fairly new to GUI programming and I'm trying to write a plotting lib in D to use with some otherwise console-based scientific apps. I'm using DFL as my GUI library.
Assume my plot form has a method called showPlot() that's supposed to display the plot on the screen. I would like to be able to have any thread in my app throw up a plot window and either block until the plot is closed or continue working, without the caller of showPlot() having to know what any other thread is doing with regard to plotting, or what plots were created in the past and may still be on screen. (The internals of showPlot() may, of course, have this knowledge.)
I'm still trying to wrap my head around how GUI libs typically work under the hood. It seems like you're supposed to only have one GUI thread, and one main form. I'd appreciate answers at the language/library-agnostic design pattern level in addition to language/library-specific ones.
Edit: To emphasize, this app has no GUI besides the plots that it throws up at interesting points in its execution. It's basically a console app plus a few plots. Therefore, there's no well-defined "main" form.
What you're going to be able to do will likely rely on how DFL works. Typically, in a GUI app, there's an event thread which handles all the events in your app - be it repaint events, button click events, mouse click events or whatever. That thread calls the event handler which is registered to handle the event (that frequently being the widget which was clicked on or whatnot). The problem that you run into is that if you try and do too much in those event handlers, you lock up the event thread, so the other events (including repaint events) don't get processed in a timely manner. Some GUI toolkits even specifically limit what you're allowed to do in an event handler. Some also limit certain types of operations to that specific thread (like doing anything - especially object creation - with actual GUI-code like the various widget or window classes that the toolkit is bound to have).
Typically, the way to handle this is to have the event thread either fire off separate threads in the event handlers and let those other threads actually handle the events, or you set some amount of state in the event handler, a separate, already-running thread is alerted to this change in state (possibly using the observer pattern), and it handles things appropriately based on that state. In either case, what the event handlers themselves do is generally fairly limited.
How GUIs work is generally very event-based. The program handles events from the user and the system and doesn't tend to a do a lot without being signaled to do it. Frequently, GUI apps don't do anything until they're told to by an event (though there are plenty of cases where a background thread is doing some sort of work separate from the events). What you're trying to do doesn't sound particularly event based, so that complicates things a bit.
My guess would be that you would need to have your app create a new window every time that you want to throw a new plot up. That window would likely be a child window of the main window which would be hidden since you obviously don't need it, and presumably DFL requires you to have a main window of some kind. There's a decent chance that each thread which wanted to create a window would have to tell the main GUI window to do that, but it depends on DFL really. It's also possible that DFL allows any thread to create new GUI elements (such as a new window).
Regardless, it would almost certainly be the main event thread which actually handles the window. The thread which wants to create a window and populate it would likely have to create the window (either directly or indirectly), and then update the state of the window by updating a set of shared variables so that the event thread could appropriately repaint the window. The most that original thread would likely to do actually repaint the window is send a repaint event to window after it's updated the state of the shared variables that hold the data necessary to paint the window. It wouldn't handle the painting itself.
As for the thread blocking, it would likely have to do busy-waiting until the window closed event was received by the event thread, and some shared variable was updated, or you could make it go to sleep until the event thread woke it up after receiving the window closed event. In the case where you didn't want it to block, it just wouldn't care about waiting to be told about the window-closed event and would keep chugging along.
In any case, hopefully that's enough information to put you in the right direction. Usually events drive everything, with everything hanging off the GUI, so to speak. But in your case, your app is using the GUI more like stdout. So, you might do better to first work on some small, fairly stupid GUI apps that are actual, normal, event-based GUI apps (like a Tic-Tac-Toe game or something) in order to get a better handle on how the GUI stuff works before trying to get it to work in a somewhat less standard manner like you are.
GUI frameworks typically have their own own event-loop, and call the application code as callbacks in reaction to external events(button clicks, timers, redraw, ...). The main difference between a "typical" console application and a GUI application is that you give up the control about when a function is called to the GUI framework.
Threads are typically used when the application code contains some long-running process, which cannot be interrupted into smaller chunks(large computations, copying files, take control over the world, ...). Then one thread is used to keep the GUI responsive, while the work is done in a separate thread. The main problem is to keep both threads correct in sync, since most GUI toolkits are not capable to handle calls from more than one thread. When you have only small work parts, which don't block the GUI for long time (<0.1s), then it is better to stay without worker threads.
I also strongly suggest to separate the GUI code and the application logic apart from each other. Having GUI code and application code mixed together is a maintenance nightmare.

Resources