In my app I import gpx and kml files to display tracks and waypoints on the map. For this operation, I use about 5 methods. Everything works fine, unless I try to import several long gpx/kml tracks with exfilechoser.
The screen goes black for some seconds, and logcat says: skipped frames ( > 600).
How could I get these calculations of the UI?
Or how could I use AsyncTask with about 5 methods? Is this possible?
There are several methods.
Do calculations asynchronously. Android SDK provides Handler, IntentSevice, AsyncTask, HandlerThread to solve problems asynchronously. By the way, it is recommanded to use multi-thread solving heavy calclations.
Let server do calculations. Mobile devices is not suitable for calculating, calculations consume power and affect app performance.
By looking at your question i will suggest you to use handler with java normal multi threading concept.
I dont think Asyntask is a very good approach to do long running tasks on background.
It's good have do calculation on server side it reduces the overhead on mobile site.
I think you should use Service which was designed for this purpose. It is said in documentation:
A Service is an application component that can perform long-running
operations in the background.
You should remember about creating new thread in service.
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work.
Related
I am mostly confused between Services and Coroutines
I don't understand why should i be using coroutines vs when should i be using Services? When i am downloading a file, do i need to use service or can i just use coroutine? Both of them can not survive process death.
And if i can download a file using coroutines, what do i need the service for at all?
Can you please list all of these and give some examples where i would want to use Service, where would i use Coroutines and where would i use WorkManager?
Also, should i be using AsyncTask at all? Because i read that it has many flaws in it and it can create memory leaks.
I also read this article about background work:
https://developer.android.com/guide/background
but it talks about only Workmanager and Coroutines but no mention of services. Why?
Background Work
https://developer.android.com/guide/background
In Android and any UI application, you have the Main Thread. If you do something heavy on the Main Thread you will block the user's interaction. So you need to do such work in another Thread. You can do this on Android using:
You create a Thread
Executor with a pool of Threads
Handler
AsyncTask
RxJava
Coroutines
App lifecycle
https://developer.android.com/guide/components/activities/process-lifecycle
But the Android application lifecycle is a complicated thing. You can't know when an application will die. It is a process that consumes some amount of resources. When the OS has no resources it will kill some applications. So you have priorities and based on them - the application is less likely to be killed. And they are part of the above link. As you can guess - if the app is visible - it is highly unlikely to die. But what if you want to finish your work, but without keeping the user engaged. This is point 3 from the link:
You can use a Service
The idea of the Services is that you can do something "in the background", but it does not mean a background Thread. It means that it is in the background for the user. The plain Services starts on the MainThread. There are specific implementations that has their own Background Thread.
And also what a Service gives you - it will make your application less likely to be killed.
WorkManager
There are many APIs in Android. During the years they become more and more. But at the same time there are more and more restrictions - with the idea that the user's battery must be saved. Also the network resources. So it is hard to pick the right API, but at the same time workaround the restrictions.
So WM was invented. It is for cases where you want your work to finish for sure at some point. Even on a device restart. But you don't care that much about timing. Uploading a video is the best example. If you want something with an exact period like every 1 hour for sure - You need to use AlarmManager. With WM it might be 1 hour, 1 hour and a half, 4 hours, 6 hours, 1 hour periods. And for the video - it might start now, you upload 30MBs and in 2 hours - the other 70Mbs.
You should use a Service when you are actively tracking or engaging with the user. Like for example Music applications, Running applications, etc.
And WM is something that underneath is using a Service, Broadcast Receivers, Room, etc. It hides a lot of complexity for you.
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.
What is the difference between thread and service in android,when downloading an image
There are lots of difference between Normal thread and a Service
Service: Due to android component it runs on UI thread but without any view shown to user. It runs in background with the same kind of property that an activity have, like you cannot run network operations (downloading image, calling web service) in service for that you have to use Thread which will run on worker thread other than UI thread.
Thread: Its an independent path of execution which can consist network operation, complex coding, huge amount of data transfer and accept. Thread is not related to android but in android it is used to perform different task. You can download an image on Thread but to show it on any UI part you have to update downloaded image on UI thread using runOnUIThread method
Please let me know if this explanation clears your doubt. If not let me know which part you did not understand and what exactly is your question.
With rare exceptions, you should never explicitly create a Thread. Threads are expensive and prone to programmer error. Use AsyncTask because it handles the complexity of thread safety and provides the optimization of thread pooling. Or better yet, if network activity is your reason for doing work outside the main thread, use one of the many network libraries that manages all of these concerns for you. Which approach is fastest is not something that can be answered generally, and should never even be a concern until you've tried the simple and clear solution and demonstrated that its performance is inadequate.
Regardless of how you make your network activity asynchronous, any network activity that is not started and completed (or cancelled) within the lifetime of a single Activity instance needs to be hosted in something else. If it only needs to survive across configuration changes, host it in a retained Fragment. If it needs to survive between different activities, host it in a Service. When choosing between these options, remember that your Activity may be destroyed any time it goes into the background or backstack.
When the user logs in into my app. I am starting an asynctask to maintain the user session. And that async task is running indefinitely till the user logs out. My problem is that when I try to start other asynctasks, their doInBackground() method is never executed.
I read somewhere that if an async task is already running, we cannot start new async task. I can confirm this because when i removed the user session async task, it worked properly. Is there a workaround?
P.S.: I have already used executeOnExecutor() method. but it didn't help.
For potentially long running operations I suggest you to use Service rather than asynctask.
Start the service when the user logs in
Intent i= new Intent(context, YourService.class);
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
And stop the service when the user logs out
stopService(new Intent(this,YourService.class));
To get to know more about Service you can refer this
Service : Android developers
Service : Vogella
To know more about asynctask vs service you can refer this
Android: AsyncTask vs Service
When to use a Service or AsyncTask or Handler?
I read somewhere that if an async task is already running, we cannot start new async task.
Yes,That is fact that you can't run more then 5 (five) AsyncTaskat same time below the API 11 but for more yes you can using executeOnExecutor.
AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). The issue is initially (in early Android OS versions) the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks. But later they fixed that and now the size is 5, so at most 5 AsyncTasks can run simultaneously.
I have figure out Some Threading rules and i found one major rule is below ,
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
What is definition of AsyncTask?
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
How & Where use it?
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended to use it.
Why you can't use multiple AsyncTask at same time ?
There are a few threading rules that must be followed for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Running multiple AsyncTasks at the same time — not possible?
Test sample of parallel excution of AsyncTasks
Try Executor
You should go with Executor that will mange your multiple thread parallel.
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
...
Sample Example 1
Sample Example 2
Just like a few others here, I object to the premise of the question.
Your core problem is that you are using an AsyncTask to perform a task beyond its scope. Others have noted this too. Those who offer solutions that can mitigate your problem through low-level threads (even java.util.Concurrent is low-level which is why Scala uses Akka actors as an abstraction), Service, etc. are quite clever, but they are treating the symptom rather than curing the disease.
As for what you should be doing, you are not the first to want to maintain a user session in an Android application. This is a solved problem. The common thread (no pun intended) in these solutions is the use of SharedPreferences. Here is a straightforward example of doing this. This Stack Overflow user combines SharedPreferences with OAuth to do something more sophisticated.
It is common in software development to solve problems by preventing them from happening in the first place. I think you can solve the problem of running simultaneous AsyncTasks by not running simultaneous AsyncTasks. User session management is simply not what an AsyncTask is for.
If you are developing for API 11 or higher, you can use AsyncTask.executeOnExecutor() allowing for multiple AsyncTasks to be run at once.
http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)
I'll share with you, what we do on our App.
To keep user Session (We use OAuth with access/refresh tokens), we create a Singleton in our Application extended class. Why we declare this Singleton inside the MainApplication class? (Thats the name of our class), because your Singleton's life will be tided to the Activity that has created it, so if your Application is running on low memory and Garbage Collector collects your paused Activities, it will release your Singleton instance because it's associated to that Activity.
Creating it inside your Application class will let it live inside your RAM as long as the user keeps using your app.
Then, to persists that session cross application uses, we save the credentials inside SharedPreferences encrypting the fields.
yes starting 2 or more asynctasks simultaneously may cause issues on some devices. i had experienced this issue few months back. i could not predict when the 2nd asyncTask would fail to run. The issue was intermittent may caused by usage of memory as i was executing ndk code in asynctask. but i remember well that it depended on memory of device.
Similar question had been asked before. I would post the link for the similar question.
AsyncTask.executeOnExecutor() before API Level 11
Some users suggest go for Service. My advice is don't go for that path yet. Using service is much more complicated. Even you are using service, you still have to deal with threading, as
Note that services, like other application objects, run in the main
thread of their hosting process. This means that, if your service is
going to do any CPU intensive (such as MP3 playback) or blocking (such
as networking) operations, it should spawn its own thread in which to
do that work....
If we can solve a problem in elegant way, don't go for the complicated way.
I would suggest that, try one of the APIs in java.util.concurrent as suggested in below
AsyncTask is designed to be a helper class around Thread and Handler
and does not constitute a generic threading framework. AsyncTasks
should ideally be used for short operations (a few seconds at the
most.) If you need to keep threads running for long periods of time,
it is highly recommended you use the various APIs provided by the
java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and
FutureTask.
I can't give you any code example so far, as I do not know how you design your session managing mechanism.
If you think your long running session managing task shouldn't bind to the life cycle of your main application life cycle, then only you might want to consider Service. However, bear in mind that, communication among your main application and Service is much more cumbersome and complicated.
For more details, please refer to http://developer.android.com/guide/components/services.html, under section Should you use a service or a thread?
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)