I Have several activities handling diferent screens with information that is loaded asynchrounously via AsyncTask.
All data fetching are done in doInBackground()
All UI operations are done in onPostExecute()
In some instances I get the error: "Can't create handler inside thread that has not called Looper.prepare()"
If I do the Looper.prepare(), it crashes if a new activity is instanced for this class.
It's a weird behaviour that I'm able to find why it happens. The other screens with similar behaviour work as expected. There are no differences between them that I can find.
Has anyone had this behaviour?
"Can't create handler inside thread that has not called Looper.prepare()" means that you are trying to call AsyncTask.execute() outside of the UI thread.
There are few rules you should follow using AsyncTask:
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Also it can mean than you are creating Handler object inside doInBackground method.
Related
what is meant by asynchronously loading data in activity or fragment in android?
This is my question. I searched everywhere. I'm not getting a generalized definition for this?. I can't get the term mentioned in android developer also.
Can anyone provide me the basic explanation of this term?
Asynchronous in Android mean that you do stuff while the user can interact with the User Interface (UI) : you are not blocking the UI while you are doing long stuff. So the user can still navigate, change activities or fragment and your data is still loading.
For data : you load it, parse it and do whatever you want in a NON-UI Thread (using AsyncTask eg) and then notify the UI, and display what you need to.
You have many possibilities to implement Asynchronous load in Android, and you have many different way to manage your request. I personnaly recommend using Retrofit if you need to use a Web API.
It means that you load your data in a separate thread than the UI thread. You launch your HTTP request for example in another thread and when it finished you notify the UI thread to refresh display.
This mean to load data in separate thread rather than load the data in main thread.Loading data in main thread may cause app to block
The AsyncTask class encapsulates the creation of a background process and the synchronization with the main thread. It also supports reporting progress of the running tasks.
To use AsyncTask you must subclass it. AsyncTask uses generics and varargs. The parameters are the following AsyncTask .
An AsyncTask is started via the execute() method.
The execute() method calls the doInBackground() and the onPostExecute() method.
TypeOfVarArgParams is passed into the doInBackground() method as input, ProgressValue is used for progress information and ResultValue must be returned from doInBackground() method and is passed to onPostExecute() as a parameter.
The doInBackground() method contains the coding instruction which should be performed in a background thread. This method runs automatically in a separate Thread.
The onPostExecute() method synchronizes itself again with the user interface thread and allows it to be updated. This method is called by the framework once the doInBackground() method finishes.
I am working on app that updates data for every 8 secs and the update was done using Async task. I am using loops to achieve this condition
while(const_val > update_val) {
new Asynctask().execute();
Thread.sleep(8000);
}
const_val will be constant and will be not be changed by any other methods.lets say this value will be 5.update_val will be updated and decremented when Asynctask is called and let's the value will be 10. So , the while loop executes until the condition is true and asynctask ,sleep are called .
When I use above while loop in a general method then UI gets locked and if I use the same loop in another asynctask there was an error saying "Only original thread that created a view hierarchy can touch its view "
You need to change your code to start the AsyncTask and have it provide an update via its onPostExecute() method. By calling Thread.sleep() you are sleeping the main thread (or UI thread) of your app, which is not good. You do not ever want to block the main thread. This article may help you better understand AsyncTask and threading in Android: http://po.st/Cei3m2
I don't think you should use a surrounding loop. Look at this example:
http://javatechig.com/android/progress-notification-in-android-example
the AsyncTask is a private inner class
the onPostExecute updates the UI with a message/cancels the load bar
This way you don't have to loop and the onCreate() can return instantly.
While reading AsyncTask documentation, the part on Threading rules, I found this:
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.
What is meant by "loading"? It's not instantiating or executing, as the documentation talked about those later.
I don't believe that this answer is actually correct.
It wouldn't make sense for the documentation to separately list instantiation and loading, if those things were actually the same. I believe this statement
The AsyncTask class must be loaded on the UI thread.
is referring to Java Class Loading. In other words, the AsyncTask class itself needs to be loaded on the main thread. In Jelly Bean (or later), this is automatic. But, in older versions of Android, there is the potential for this class to be loaded on another thread, which can cause problems.
See this Google discussion for more information. Basically, there are conditions (for example, code using IntentService) that can cause the AsyncTask to be first loaded on the wrong (non-main) thread.
The simplest fix for this, prior to Jelly Bean, seems to be to use something like:
Class.forName("android.os.AsyncTask");
in the Application's onCreate() method, to force class loading to happen when you want it to.
Creating the AsyncTask instance is probably what you think it is ... instantiating it:
MyAsyncTask task = new MyAsyncTask();
and that should also be run on the main thread.
Is it possible to execute an AsyncTask from Runnable? in my experience it can be done, but not safely. When my app first runs my AsyncTask runs fine from the Runnable. But when the app is moved to the background, then brought back forward I get "Can't create handler inside thread that has not called Looper.prepare()".
Here's what I'm trying to do:
I'm using MapView and invoking runOnFirstFix(Runnable) within onCreate. My Runnable calls an AsyncTask to perform a web service call which returns some data based on the location.
I move the app to the background (by tapping the home button), after some time I bring my app forward again and I'm getting the exception at the point where I'm invoking execute() on my AsyncTask.
First of all, why is runOnFirstFix being executed again? Secondly, why is it causing the exception the second time around?
I'm guessing that there is some part of the lifecycle that I don't understand.
Thanks.
It wasn't initially obvious to me that the AsyncTask needed to be called from the UI thread. So when runOnFirstFix ran the second time it was from withing a Runnable which wasn't on the UI thread. To solve the problem I simple created another Runnable inside the first to run the AsynchTask.
And the reason my runOnFirstFix seemed to be called twice was simply because I was creating a new instance of it.
Can someone explain to me what exactly the UI thread is?
On developer.android.com it says about the runOnUiThread function
public final void runOnUiThread (Runnable action)
Since: API Level 1 Runs the specified action on the UI thread. If the
current thread is the UI thread, then the action is executed
immediately. If the current thread is not the UI thread, the action is
posted to the event queue of the UI thread.
Does the UI thread mean that this will be run everytime the activity is pushed the the background by some ui activity like incoming call or screen dimming etc.? If not, what exactly does the UI thread include ?
Thank you
The UIThread is the main thread of execution for your application. This is where most of your application code is run. All of your application components (Activities, Services, ContentProviders, BroadcastReceivers) are created in this thread, and any system calls to those components are performed in this thread.
For instance, let's say your application is a single Activity class. Then all of the lifecycle methods and most of your event handling code is run in this UIThread. These are methods like onCreate, onPause, onDestroy, onClick, etc. Additionally, this is where all of the updates to the UI are made. Anything that causes the UI to be updated or changed HAS to happen on the UI thread.
For more info on your application's Processes and Threads click here.
When you explicitly spawn a new thread to do work in the background, this code is not run on the UIThread. So what happens if this background thread needs to do something that changes the UI? This is what the runOnUiThread is for. Actually you're supposed to use a Handler (see the link below for more info on this). It provides these background threads the ability to execute code that can modify the UI. They do this by putting the UI-modifying code in a Runnable object and passing it to the runOnUiThread method.
For more info on spawning worker threads and updating the UI from them click here
I personally only use the runOnUiThread method in my Instrumentation Tests. Since the test code does not execute in the UIThread, you need to use this method to run code that modifies the UI. So, I use it to inject click and key events into my application. I can then check the state of the application to make sure the correct things happened.
For more info on testing and running code on the UIThread click here
If you execute blocking code (e.g. a Http-Request) in a separate Thread, consider using AsyncTask. Its doInBackground-Method runs on a separate Thread. AsyncTask provides you with methods onProgressUpdate and onPostExecute which are guaranteed to run on the UI thread.
If you need GUI-progress updates (e.g. via a progressbar) call publishProgress inside doInBackground. This leads to a subsequent call of onPublishProgress which is also guaranteed to run on the UI thread.
onPostExecute is automatically called after doInBackground returns.
All UI drawings etc. happen in a separate thread. Its called the UIThread. If you want to make any change to UI u must use make sure it happens in UIThread's context.
Easiest way of doing it is to make use of runOnUiThread