I know there are a lot of threads relating to this topic on here, but I haven't read a real answer to my question, and a lot of them are from 2010 when there didn't seem to be as much emphasis on keeping tasks off the UI thread.
I need to make a database query that is just intensive enough that it causes a noticeable delay in UI response (on my S5, so it'd be worse on a lot of phones). I want to push the query to another thread. I've been doing so with ASyncTask, but I'm reading that there are issues with ASyncTask and things like the screen rotating, interrupting apps, and memory leaks. The recommendation I see everywhere is to use a CursorLoader, but the constructor for that requires a Uri because it's designed for content providers. Not only does a content provider seem like a bit of overkill for my app, but the content provider tutorial page from Google specifically states "You don't need a provider to use an SQLite database if the use is entirely within your own application."
So my question is what, if anything, lies between ASyncTask and a Content Provider? Is there any implementation of CursorLoader for internal databases? Maybe a more robust implementation of ASyncTask?
I've been doing so with ASyncTask, but I'm reading that there are issues with ASyncTask and things like the screen rotating, interrupting apps, and memory leaks.
AsyncTask is a bit tricky to use properly. Having one be managed by a retained fragment (e.g., a model fragment) helps.
Is there any implementation of CursorLoader for internal databases?
None that work well. I say this having written (and since deprecated) one. The Loader interface is an abstraction designed around a singular use case: ContentProvider.
Maybe a more robust implementation of ASyncTask?
It's not that AsyncTask needs to be "more robust", but that you have to be aware of the various problems with it. For example, the vaunted CursorLoader uses an AsyncTask.
At the end of the day, all AsyncTask does is use a background thread from a thread pool and mediate communications back to the main application thread for the results of the work. There are any number of ways of accomplishing the same end. Presently, I'm fond of using greenrobot's EventBus (or one from a thread pool, if there might be lots of simultaneous events), in conjunction with an ordinary thread. Beyond that, you can:
Use an ordinary thread with a Handler
Use an ordinary thread with post() on a View
Use an ordinary thread with runOnUiThread() on an Activity
And all of those presume that the work is reasonably short and disposable, as would appear to be your case. For longer and/or less-disposable bits of work, use an IntentService, possibly my WakefulIntentService if the work might take dozens of seconds or more.
However, all of these still have issues, in some cases the same issues that AsyncTask itself has (e.g., addressing configuration changes properly). There is no "silver bullet".
Related
I am developing a Java Desktop Application and I am creating a file and writing small content to it 10-50 lines.
I am doing this in Main Thread, shall I do this File I/O on a Background Thread?
I understand the fact that any intensive operation blocks the Main Thread so Background Thread is recommended but I dont observe any lag/hang in my Application while doing this File I/O.
So What is the best way or its ok to do small File I/O on main Thread.
The key thing is: you should write your code so that it is easy for you to make a change.
You see, the question "should it happen on a background" thread might result in different answers over time. Maybe today, when you do that once in a special situation, it is fine. But what if you start doing it more often in future versions of your program? Then it might become a problem.
In that sense: simply expect that this is one corner of your code that requires updates in the future. So design it in a way to quickly change that.
Having said that, in "general": prefer the background thread. Threads are pretty cheap on modern hardware. And java provides you a lot of reasonable abstractions that make it pretty easy to use background threads (think of a pool-based central ExecutorService for example). On the other hand: response times to users are always critical.
Thus I would heavily lean towards a background-thread based solution. Because in 2017 that is the almost a natural thing to do.
You are just writing few lines in file, so why to go for background? it will be better to keep it in main thread so that you can get proper exception handling in case of failure.
My application is currently using ordinary threads to produce servers, clients and even a thread which swaps WiFi networks and starts the previous. Those threads run in the background and dont have any impact on the UI so it is something I was looking for, but the problem is that when I reenter the application all those threads are recreated. Is it possible to create a singleton thread which will be possible to control when we reopen the application?
Android offers some classes also:
Service: but it uses the UI thread...
AsyncTask: probably a better candidate
IntentService: has a worker thread which could be manipulated? Probably best option from above.
Any thoughts/opinions will be highly appreciated. :)
EDIT:
Also why I would want to change my ordinary threads into some other method is because Android will prioritize ordinary threads to get killed.
Thread call hierarchy:
MainActivity -> NetworkSwap(infinite process which is scanning, connecting and swaping WiFi networks), ServerTCP(infinitely listening for connections) , ServerUDP(infininetely listening for connections)
Networkswap -> ClientUDP (sends broadcast request to serverUDP and ends)
ServerUDP -> ClientTCP (sends request to serverTCP and ends)
It's still not entirely clear to me what you're using these threads for. From the title it seems you're doing ongoing work, but in the description it sounds like sometimes you do smaller discrete chunks of work. It's also not clear whether these types of work are related.
That said, with ongoing work I'd say to move your currently existing thread to be managed by a regular Service, thus giving a lifetime that is independent of activities and can do ongoing background work. For smaller discrete chunks of work, IntentService is a better match. If you have these two types of work and they're not very related, you could even consider having both types of services (it sounds like you have multiple threads as is anyway).
I can't seem to find any documentation on the details of an Activity's run loop for Android.
Apple documents the "anatomy of a run loop", and that's pretty much what I'm looking for. The Android documentation just says "Activity Is Running" in its life cycle state diagram. Obviously that's backed up by some sort of run loop.
Anyone have some insight (aka Documentation) into the internals of an Activity's run loop?
edit - I should clarify that I presume the run loop is actually owned and run by the main UI thread. The current Activity's functionality is likely injected into this runloop at a certain point. I'm interested in the overall UI thread run loop, as well as what role the Activity takes in it.
The short answer is, "don't worry about it, it's done for you."
Activities and other constructs sit on top of android.os.Looper, communicating with it through instances of android.os.Handler. A Looper manages your "run loop," dispatching messages from a queue and blocking the thread when it's empty. Handlers communicate with a thread's Looper and provide a mechanism for working with the message queue.
Most of the time you won't need to work with either one directly. Lifecycle events for your major application components like Activities and Services will be dispatched to your code. If you're curious as to what's under the hood, sources for both are available:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Looper.java
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Handler.java
Updated:
There's really nothing specific being referred to by "Activity is running." The Activity is simply displaying its UI, handling input, executing any necessary functions, and starting another Activity.
If you're interested in what implications multi-threading would have on the run-loop, there isn't really a concrete relationship. Your threads can just do their work, and the Activity's state will function independently and automatically update its UI (provided you call postInvalidate() correctly).
Original:
Take a look at the first diagram on this page: http://developer.android.com/reference/android/app/Activity.html
It specifies the "lifetime" of each Activity and what states it can be in, if that's what you're looking for.
In Swing, the GUI is supposed to be updated by the EDT only, since the GUI components are not thread safe.
My question is, if I have a single thread, other than the EDT, that is dedicated to update a specific component, and this component is not accessed by any other thread in my program, only this dedicated thread, is it ok? In my case I have a JTable and a thread receives information from the network and updates the table (without using EventQueue.invokeLater). All the other components are updated from the EDT. I have not seen a problem so far, and I was wondering if a bug will surface eventually.
UPDATE
My purpose was to update the table in real-time. The data come constantly from the network and for this I dedicated 1 thread just for the table, to update it constanlty as they come. If I use the SwingUtilities.invokeLater, this means that the table will be updated when the EDT is available. Is not swing supposed to be used for real-time update requirements?
Instead of trying to reason about whether it will or won't work, I would just stick to the well-known 'rule' which is that you should only interact with GUI components using the event dispatching thread. When you receive data from the network, just update the table using SwingUtilities.invokeLater (or invokeAndWait).
You might not see problems straight away, but it's quite possible you might do in the future.
There are a few methods documented as thread-safe. I believe a few less in JDK7, because it turns out some of them are unimplementable as thread-safe. For the most part Swing is thread-hostile - it has to be used from the AWT EDT thread. This is largely because it uses EventQueue.invokeLater internally at "random". Also there is hidden shared state (you can change the PL&F without having to tell each component for instance). Some classes you may be able to treat as thread-agnostic, but they are not documented as such.
So the answer is, always use the EDT for Swing. As with most threading bugs, you might seem to get away with it and then suddenly fail in production. The bug is likely to be difficult to diagnose and reproduce (particularly if it only happens in production on certain systems). Fixing a code base that is severely broken may not be fun. Keep it clean from the start.
You must update GUI components on the EDT. Period. (There are a couple of legacy exceptions to this rule - but they were all silently putting things over to the EDT anyway). The EDT operates as a message pump (as most windowing systems do) - you have to live within that constraint if you want to update GUI components.
If you want your table to update quickly, keep the EDT clean - don't put any huge load onto it.
If you are working with updating live tables, I strongly recommend that you take a look at GlazedLists - they have a very, very good SwingThreadProxyList implementation that takes care of efficiently posting updates to the EDT. You have to agree to drink the GlazedLists koolaid to go this route, but it is mighty tasty koolaid (I love GL).
Is not Swing supposed to be used for real-time update requirements?
No. You may be able to update your data model at a sufficient rate, but the GUI is typically subordinate. You may be able to take advantage of any network latency in your environment. Alternatively, you may need to consider something like Oracle's Sun Java Real-Time System.
You can improve the "liveness" of the EDT by keeping updates brief and using the minimal, correct synchronization. Several alternatives are discussed here.
It is an absolute rule, unless you want race conditions. The event dispatch thread is fast enough for our CCTV app's display not to need hacks.
Normally in a C or C++ program there's a main loop/function, usually int main (). Is there a similar function that I can use in android Java development?
As far as an Android program is concerned there is no main().
There is a UI loop that the OS runs that makes calls to methods you define or override in your program. These methods are likely called from/defined in onCreate(), onStart(), onResume(), onReStart(), onPause(), onStop(), or onDestroy(). All these methods may be overriden in your program.
The fundamental issue is that the OS is designed to run in a resource constrained environment. Your program needs to be prepared to be halted and even completely stopped whenever the OS needs more memory (this is a multitasking OS). In order to handle that your program needs to have some of all of the functions listed above.
The Activity lifecycle describes this best (your program is one or more Activities, think of an Activity as a screen).
Bottom line: Your program 'starts' at onCreate() through onResume() but the OS is running the loop. Your program provides callbacks to the OS to handle whatever the OS sends to it. If you put a long loop at any point in your program it will appear to freeze because the OS (specifically the UI thread) is unable to get a slice of time. Use a thread for long loops.
In Android environment, there is no main(). The OS relies on the manifest file to find out the entry point, an activity in most case, into your application.
You should read http://developer.android.com/guide/topics/fundamentals.html for more detail.
According to:
http://developer.android.com/guide/tutorials/hello-world.html
The application class must support a method for each activity that the Application
supports. In the general case, the onCreate is probably equivalent to the main/top
function for your needs.
Maybe it's possible by creating a timer and execute custom functions at every tick, reset the timer when it's at a specific time
The above answers provide a "why" as to there's no "main loop" on Android (which is important to understand). I'll offer a solution to the implied question, instead, as many visitors here will be looking for exactly that.
I believe the appropriate thing to do, here, would be to create an AsyncTask which operates as your "main loop". Or better yet, design your main loop to run as a java.util.concurrent future, which can be started and ended during lifecycle events (like rotation!), using signaling (keep your data separate). The AsyncTask API is deprecated, because it was complex, and handling it properly amounted to writing code that would, effectively, operate as an AsyncTask which cleaned up when the next problematic lifecycle event transpired.
Keep in mind that this will be a separate thread from the UI, and, as such, will be required to respond in short order to UI thread events, like "onPause" and "onDestroy". If your app does not respond within a certain period of time (~5 secs, iirc) to these events, or user input events, it will be killed by the OS. It's really prudent, for a real-time app, to be able to fully respond to these events in under 1 sec, even on the lowest-end device. You can use synchronization primitives to notify other threads that their response is pending, and they can use them to signal when they are finished (or simply end, in the case of a future).