I'm trying to optimize my android app, it's a big app and it's taking a lot of battery while running. So I'm trying to see what I can do to fix that.
I ran DDMS and looked at the threads, there are a lot : almost 30. The ones I create through instances of AsyncTask are in "Wait" state. In my code I create them, run some code in "doInBackground" and never touch them again.
From what I understand so far, it means they are done working for now, and something called "Object.wait()" on them.
So first : What is this something, how does it works ?
And : Every time I want my code to run in a new Thread, I create a new AsyncTask instance. Does this "something" wake the old thread, or should I keep a trace of the thread, destroy it when I'm done ?
Thanks for helping me understand.
The page
http://developer.android.com/guide/components/processes-and-threads.html
tells that "To use it, you must subclass AsyncTask and implement the doInBackground() callback method, which runs in a pool of background threads. "
So as a matter of fact AsyncTasks will reuse the old threads.
Related
I am learning Android app development from Udacity.com by Google engineers and they said,
"It is not a good idea to use 'AsyncTask' as it is not attached to an activity life cycle. The virtual machine will hold on to the activity object as long as the Asynctask is running, even after Android has called onDestroy( ) method for the activity and expect it to be discarded.
If you rotate your phone, the behavior is to destroy the current activity and instantiate a new one. The naive AsyncTask implementation now has two threads trying to do the same update. So it is not the best pattern for a potentially very long running background operation , such as fetching from web services. If you leave the app, the asyncTask will run as long as as the process is kept alive , but will run at a lower priority, and your process will be the first thing to be killed if the device needs more resources. "
1) If using AsyncTask is disadvantageous why was it created? What would have been the design philosophy or the cause to create it in spite of having services(or something similar to achieve same kind of functionality)?
2) What are the situations where Asynctask should be used for betterment compared to Services/similar options available in Android?
3) What are the situations/places Asynctask should never be used?
Please do not downvote this question. I searched Stackoverflow and I couldn't find a similar question.
Advantages of AsyncTask
Provides generic solution for all network calls
Publish progress to UI while executing.
Run Asynchronously
Easy to maintain and read.
Problems in AysncTask
When you rotate your screen, Activity gets destroyed, so AsyncTask will not have a valid reference to publish data from onPostExecute(). In order to retain it, you need to usesetRetainState(true) if calling from fragment or onConfigChanges() if calling from activity method of an activity.
If activity gets finished, AsyncTask execution will not cancelled automatically, you need to cancel them else they will keep on running in the background.
If any exception occurs while performing network task, you need to handle them manually.
Whereas AsycTask, Services, IntentService, Threads all run on different threads and all serve different purpose.
please read more detail here.
So you need to decide when to use which component while performing non UI operations.
My Main thread seems to be pretty bad with performance. Transitioning between activities results in significant delays. I have pushed all of Web/Bitmap/File work into AsyncTasks and yet this is still happening. I have been doing my head in trying to figure out what is causing the slow-downs.
My question is - If the Main thread uses a class (say ImageDownloader) that creates its own little AsyncTasks (say ImageDownloadTask), will Main wait for ImageDownloader to finish it's AsyncTasks (hence delays?)
I would love to post code, but it's a very large project. If there is anything specific I should look for, please let me know and I'll be sure to share.
If you haven't already done so, I recommend you enable strict mode and look for activity on the main thread that way.
Check your onCreates and onResumes for anything that might run for more than an instant. This includes network calls, database calls, loops that may have a lot of iterations, and even reading from locally stored files (SharedPreferences read from an xml). Also try to benchmark how long your onCreate executes the setContentView method -- I believe nested LinearLayouts cause significant performance hits especially in complex UI structures. Acquiring a location with the LocationProvider, when not done properly, will also cause severe performance issues.
You may think you are fine with passing off long-running threads on an asynctask, but you also need to check that prior to starting these tasks, the data you need to start them may take a while to acquire.
A small part of my application checks if files exist on the user's device. The list of files is potentially quite long - apparently long enough to cause ANR's with a few users. A thousand files is by no means impossible.
The code is quite simple:
new File(fileUrl).exists()
I'm currently doing it on the main thread, as I need the operations to be blocking. I could do it using an AsyncTask class and then continue the rest of the work once it's done, but I'm wondering if that's a valid cause?
All the work is being done in a background Service, if that changes anything. I'm also potentially going to experience orientation changes, and that might be annoying with AsyncTask. Would a Handler be better?
So, to sum things up: Should I do use an AsyncTask for a potentially long-running operation in a background Service, where orientation changes may occur?
Firstly, a Service isn't affected by orientation change - it's only the currently running Activity class which is destroyed / recreated.
Secondly, an AsyncTask isn't of much advantage in a Service as it's designed to be able to interact with the UI. It would give the advantage of doing work on a separate thread but the rest of the methods would basically be redundant.
I'd recommend using an IntentService which manages its own worker thread to do work. See the IntentService documentation
I'm new to the idea of Threading, but not asynchronous behavior. My Android app is taking ~180 millisecond to start up and ~550 milli when I use GoogleAnalytics trackViewPage method and MobFoxView constructor. Coming from Actionscript 3, anything that "took time" was automatically async and I was forced to handle it with listeners which is a bit different in Android it appears. It seems I'M responsible for deciding when something should be asynchronous. So I guess my question is, HOW do I decide what should be async? Is it by milliseconds of executing? But perhaps that changes greatly between devices. Perhaps it should be by ... or is it by ....?
You need to know one important thing - by default everything you do without starting separate thread is executed on "main" thread (also knows as UI-thread).
If you do something, which can block - your UI will lag and users will suffer.
If you doing something, which is not about UI but about database query, network call or potentially long blocking operation - you need to start thread directly or use AsyncTask.
Also you must note, if you try to do something with UI (e.g. set value to a TextView) from not-main thread you will fail. UI can be acessed only from UI-Thread.
Consider a simple Android application: there are two TabActivities and a thread in the background getting integer values from a server. If the number is even, it must be displayed in the first tab otherwise in the second. Obviously I will be doing something more complicated, but this is the basic pattern. How do I go about doing this? I have been scratching my head for about a day now and here are things I have come across:
Use of EventHandlers. The two TabActivities register for listening for my_events and when a value is received by the thread, it 'throws my_event' and then specific methods in both these activites are called and the value is passed.
The use of Handlers.
I have not used both of these concepts before and I would like to know which might be the better/correct route to take. Further, any more tips along the chosen route will be appreciated. Also, should this thread be run from a service class?
When you create your thread just pass the objects of your tabs into it, then in your execution you can easily put the text you want into tabs.
Possibly you want to look at using an AysncTask. If you do this you want to insert the values into the appropriate tab in the onProgressUpdate() method. Since the arguments passed to this method may not actually be able to represent the incoming data sufficiently you'll just want to put the new data somewhere that it can be accessed from the onProgressUpdate() method, probably in a member variable. Keep in mind that access to this member variable probably needs to be synchronized because code in onProgressUpdate is running on the application's main thread, while code in doInBackground is running on a background thread so code in these methods will be running concurrently.
AsyncTask uses Handlers transparently for you, but you could use raw Handlers if you wanted. The basic things you need to keep in mind are
You can/should only update the UI from the main application thread
Code in a Handler will always run on the Thread that created the Handler
Handlers must be created on a Thread that has a Looper (the main Thread has a Looper)
Be careful if creating the Handler as an anonymous inner class or handing it a reference to a Context since this creates the potential for a memory leak
Possibly the Thread should be invoked by a Service, but if the Thread only needs to exist when there is a UI for it to update there may be little point to this.