So over the last few months I've created a fairly complex game that's near ready for release. The only problem left is that it is running as smoothly as I would hope and I think this is because of the way I have structured my threads. Right everything in my code is done through a surfaceview. All calculations, position updates, drawing, collisions, etc are done there. I was wondering if I am supposed to put all updates into one thread then handle only drawing in the surfacethread. Is this the proper way to do it, if so how would i implement that(asynctask,thread,handler,etc)?
Sure, you should avoid doing any time-consuming calculation in the UI Thread. You could also incur in an ANR error message.
You can either use:
AsyncTask, but be aware that it has some flaws and drawbacks. For example it isn't guaranteed to even start or complete.
IntentServices or HandlerThreads if you need to do operations that need to be executed sequentially in a worker thread
WorkerThreadPool if you need to execute true parallel tasks.
Related
I'm currently learning Android programming and I'm doing my first application using VS 2017 in C# (Xamarin). Right now I'm trying to understand how to split a complex computation into several threads - more accurately, the features I should look into.
Now, what I want to do is to iterate over all possible values of an unsigned int and perform some computation on it. It's a search, so some of those numbers will be of interest and I need the threads to update a progress bar and some view containing any results found so far. The complexity here is the huge number of operations that will be performed.
I've looked into Async Tasks, Thread Pool Executor, Thread Factory, Blocking Queues and Runnables. So I'm thinking a Thread Pool sounds like the way to go, especially by specifying how many processors are available and how many threads can be used.
Going by this SO question/answer, I would use an Async Task for a short operation and Java threads for more complex operations. So, despite using C# Xamarin, I guess I'm looking into Javal.Util.Concurrent.Thread's..
My goal with all this, is to allow the user to start this complex task and pause it at any point, or abort, as well as save the search state at any point to resume later. To do this, I want to subdivide this search on all possible uint values into multiple tasks - perhaps thousands of small tasks that could be executed by worker threads. For the pause feature, I was thinking the example in Android's documentation, that I previously linked, which implements Pause/Resume methods in a custom Thread Pool Executor. The save/store should be easy.. if my tasks are ordered all I need is to keep track of the last value tested and fruitful values.
I've setup a custom Thread Pool Executor, Factory and Runnables. However, I am quite confused as to how to do two things:
How exactly should I add runnables to the queue? And from which thread?
How, and where, do I know when the search was completed? What happens to the minimum number of threads in the Thread Pool Executor when the job is completed? I want to destroy all the threads when it's over.
In my operations I could have thousands of tasks. In fact, I can decide between 4096 large tasks, or 65536 smaller tasks. They can be identified by a range of uints to be checked, or a single uint index. But either way I know ahead of time how many they are and I think it would be more efficient if I didn't have to create that many runnables... Is there a way I can customize how the threads will pick up their next work from the Queue?
Or perhaps the Thread Pool Executor is just not the right tool for what I'm trying to achieve here?
I'm mostly looking for some insight on the multithreading tools available in Android and how can I go about implementing a proper solution for my problem.
You should definitely have a look to reactive programming http://reactivex.io/ and https://github.com/ReactiveX/RxJava
This is the best and cleanest way to execute tasks in background, for example you could do :
myObservable
.subscribeOn( Schedulers.io() ) // Thread where you execute your code
.observeOn( AndroidSchedulers.mainThread()) / Thread where you get result
.subscribe(...)
I'm new in Android and multithreading programming and I read in the Android.developers docs that:
It is not recommended to manipulate a view from an other thread than
the UIThread.
Ok I accepted the rule but now I would like understand why? Anyone have a simple example for me to understand why?
Thanks in advance for your help
As was stated in the comments, to avoid race conditions is part of it. Its also just a bit of bad practice. UI Thread should handle UI issues, that's what its there for. Other threads should handle other issues, that's what they're there for.
Consider the situation of having a class that modifies a TextView based on some remote query. For this you should use something like AsyncTask which allows callbacks to the UI Thread.
Now if there is ever and instance where multiple threads are working on the same UI component, what may happen is that the "wrong" (unintended) one finishes first. This is a race condition.
Also, good programming encourages a separation of concerns. You don't have the manager working on the painting that the artist is working on, so why would we imitate this behavior in software?
The upshot is: the UI should always be responsive. So if you have
some operation that will take enough time that the user will notice,
you might want to consider not running it in the UI thread. Some
common examples are network IO and database accesses. It's something
of a case-by-case basis though, so you have to make the call for
yourself a bit
A thread should be used in a long running process that would block
the UI from updating. If it's more than a second or two you
might want to put it into a background thread and notify the user
with a dialog or spinner or something. If you lock the UI thread for
more than 5 seconds the user will be prompted with a kill or wait
option by the OS.
I have been working on an Android application that uses Google maps and then runs some lengthy network intensive operations in the background. Currently, I am using a thread to run them on and they take anywhere from 30 seconds to 7 minutes to finish. After watching a few courses on Pluralsight about AsyncTasks and Background services, I now know that threads should ideally not be used for anything taking more than a few seconds. I am now altering my solution to run live with GPS rather than taking several minutes to perform the operations. The goal is to update an array every OnLocationChanged event.
I am having trouble in thinking about how I could alter a global array every OnLocationChanged event while also accessing it from the UI main thread. What is my best option for accomplishing this? Would I be able to use a process or AsynTask to accomplish this or would I need to go client/server route? Where would the OnLocationChanged be called?
First off, onLocationUpdated is called on the UI thread. So you don't have to worry about multithreading there.
Secondly- if you have a variable that needs to be touched by two threads you just use a semaphore and take it before you need to access it on each thread, and release it when done. Make sure to keep that block of code as small and quick as possible. There's more advanced stuff you can do for high performance needs, but that's good enough for 99% of code.
Thirdly- as I mentioned in my comment, your understanding of threading is wrong. The UI thread should not be used for more than is needed. AsyncTasks should not run for more than a few seconds (as there's a single thread they run on by default, so running long would block other requests). But a Thread can run as long as it needs to, and should be used if it needs long term background processing.
In my app, I have to call a method which does some heavy work (I can feel device lagging). To avoid this I created an AsyncTask and it works perfectly fine.
I implemented the same thing using a Thread and here, too, it does not give any hiccup and works fine.
Now my question is which one better performance-wise - AsyncTask or Thread.
I know AsyncTask uses a threadpool to perform background tasks but in my case it will be called only once. So I don't think it will create any problems.
Can someone throw some light on it. Which one should I use for better performance?
Note: Both are being called in my Activity e.g. from UI the thread.
Can someone throw some light on it. Which one should I use for better
performance?
I think if you imagine case when you start once native Thread and AsyncTask i think that performance won't differ.
Usually native threads are used in the case if you don't want to inform potential USER with relevant information about progress in some task via UI. Here, native threads fail because they are not synchronized with UI thread and you cannot perform manipulating with UI from them.
On the other hand, AsyncTask combines background work with UI work and offers methods which are synchronized with UI and allow performing UI updates whenever you want via invoking proper methods of its lifecycle.
Generally if some task lasts more than 5 seconds you should inform USER that
"something working on the background, please wait until it will be finished"
For sure, this can be reached with both in different ways but this strongly depends on character of your task - if you need to show progress of task(how much MB is already downloaded, copying number of files and show name of each in progress dialog etc.) or you don't(creating some big data structure in "silent" only with start and end message for instance).
So and at the end of my asnwer:
Which one should I use for better performance?
Completely right answer i think you cannot get because each developer has different experiences, different coding style. How i mentioned, their performance not differ. I think that it's same(if you will read 50 MB file, it won't be faster read neither native thread nor AsyncTask). It depends again on character of task and your personal choice.
Update:
For tasks that can last much longer periods of time, you can try to think also about API tools provided by java.util.concurrent package(ThreadPoolExecutor, FutureTask etc.)
Async tasks are also threads. But they have some utility methods that make it very easy to small background tasks and get back to the UI to make changes to it. The performance would depend on your specific use case. Making absolute statements as to which one is always better would be simplistic and meaningless.
Note that the main advantage of Async tasks over threads is that Async tasks provide helper methods such as onPreExecute(), doInBackground(), onProgressUpdate() and onPostExecute() which make it very easy to perform short background tasks while also interacting with the UI (such as updating a progress bar). These kinds of methods are not available in generic Threads. Basically, Async tasks are threads with UI interaction component built in. Yes, you can use workarounds to try and update the UI from regular threads as well but Async tasks have been specifically built for this purpose and you don't have to deal with Context leaks and so on if you follow it's abstractions.
Async tasks are created to make developers' lives easier.
To sum up:
Async tasks are also threads
Async tasks make it easy to interact with UI while doing short background tasks
Neither is inherently more efficient. It depends on what you want to do.
Good rule of thumb: Use Async tasks if you need to get back to/update the UI after you are done with your background task. Use a regular thread if you don't.
The most common use of Thread are short-term tasks because they need a lot of power and tend to drain the battery and heat the phone up.
And the common use of AsyncTasks are lengthy tasks because of the same battery drain.
But a Thread is far more powerfull, because an AsyncTasks internally uses a Thread itself, but you don't have to configure that much.
ASYNC TASK and Thread do the same thing,
The difference is that you have more control on bare thread and you can benefit from the power of CPU in terms of complex implementation, the velocity of performance depends on your approach on how you implement the threading.
Depending on this article I can say that asynchronous multithreading is the fastest way to perform complex tasks.
https://blog.devgenius.io/multi-threading-vs-asynchronous-programming-what-is-the-difference-3ebfe1179a5
Regarding showing updates to user on UI thread, you can do that by posting on UI from the background thread (check UIhandler and View.Post)
I have an Android app that has separate things going on but are all basically threads (and definitely are threads to the Android debugger)
There are multiple animation listeners that loop and call each other
There is a countdown timer that is always counting down to zero after it is initiated
Now I need to consider adding more countdown timers. How many of these kind of looping processes can I have going on? In this particular implementation I am not concerned about performance, efficiency, etc, until it becomes apparent.
Insight appreciated
I would be very surprised to learn that you exhausted the number of threads you can use safely in an android application, as long as you are properly managing their lifetime and prevent "busy loops"and the like from occuring.
One thing I did learn though, I am pretty sure you can only have 5 asynctasks operational at any time, and they will arbitrarily continue to exist and get killed or respawned by themselves if you start new ones...ie if i turned an asynctask on then off five times the debugger will say 5 async threads operational, but I can continually toggle on and off as much as I want because the resource pool will kill the oldest dead asynctask.
There is no maximum that I know of. I can tell you, however, that you most likely don't NEED that many threads.
You can keep countdown listeners in a single thread using Android's Handler, specifically the postDelayed() method. Start a Looper in a separate thread, and use a Handler to manage the timeouts -- don't busy wait, or sleep-loop.
I don't believe countdown timer will create threads--it should simply add your task to a queue on your main thread from the looks of it.
All your listeners should take place on the same thread as well (there is a single thread that manages all listeners (for visible objects anyway).
So you probably aren't using anywhere near as many threads as you think you are. If you were creating a lot of threads I'd be worried--they are really hard to keep synchronized and may cost you a lot more than you'd gain, but with the structures listed I'd go ahead and allocate as many as you feel appropriate (but test for performance on a cheap device of course)