How to run two fragments each with their own AsyncTasks - android

I have a layout with 2 tabs in it which are implemented via fragments i.e. each tab has its own fragment. They is a SwipeRefreshLayout in each of the layouts associated with the fragments.
Also there are two async tasks which make an http call to a script that returns JSON data.I implemented the first async task and it worked fine but however when I tried executing the second one the app keeps crashing. Log cat is not of much help but these were the most important lines I saw:
java.lang.RuntimeException: An error occured while executing doInBackground()
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
These errors occured when an http request was created. Any idea how I can get around this?

In a different thread from the UI thread you must create a Handle and send a runnable for the UI thread . follows the code
Handler handler = new Handler (Looper.getMainLooper());
handler.post (new Runnable () {
#Override
public void run () {
// ... Update view
}
});

Related

Android background task

I need to start background task. Task call async http request and if condition is valid show alert.
I implemented it but I receive this error:
java.lang.RuntimeException:
Can't create handler inside thread that has not called
Looper.prepare()
This is my java code:
Timer timer = new Timer();
timer.schedule(new RequestScheduledTask(), intervalTask);
class RequestScheduledTask extends TimerTask {
#Override
public void run() {
myCall();
}
}
Can you help me please?
Thanks
Luca
for example I need refresh adapter list when data is changed. Data returned from webserver could to be changed or not. if it is changed I must refresh listview/adapter, else nothing.
myCall call server, get data response (using other framwork like volley) and then update list view.
When myCall start I want display loading indicator but when I show it, app crash with runtime exception
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
According to the following post you are doing something in a thread that is meant to be called on the main thread! What is myCall(); doing?
Can't create handler inside thread that has not called Looper.prepare()
And don't do http request with async tasks thats bad practice.
I would recomment to use volley:
http://www.itsalif.info/content/android-volley-tutorial-http-get-post-put
[edit]
Okay its the loading indicator that is should be called on the main thread. I guess you are doing it in the AsyncTask.
You can use Activity.runOnUiThread(Runnable()) to run a runnable to display it.

Cannot create handler in main thread?

A user is getting an error on their phone when executing the code below, I am checking to see if the user is currently on a call or not before I run an AsyncTask making a Web Service call. The reason I am doing this is because some people are losing internet connection when on a call so i check every 5 seconds to see if they are on a call or not. If they are not then AsyncTask gets called
do{
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run() {
onCall = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
.getCallState() != TelephonyManager.CALL_STATE_IDLE;
if(!onCall){
new CallRegWS().execute();
}
}
},5000);
}while(onCall);
I do not have the full stack trace only this showing me the error
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
obviously not too helpful but that is all I have to go on. they keep getting that error so it must be happening when I create the handler.
All this is done in the main thread so I dont know what the problem is, any insight on how I could fix this?
Update
this is called from a service and the method is in a separate class
Try Handler handler = new Handler(Looper.getMainLooper());
Also, see this post regarding this error: http://levinotik.com/loopers-handlers-runtimeexceptions-explained/
First of all you have to know that, Handlers automatically attach to the thread where are created as specified in the documentation:
Handler Class Overview
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue. Handler | Android Developers
Now, taking that on count and since the current thread don't have a message queue, in order to work properly the thread needs an actual "Queue", and that's exactly what the system is telling you to do, by calling Looper.prepare() you are creating a Message Looper within the thread you created because by default Threads do not have a Message looper as mentioned in documentation:
Looper Class Overview
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped. Looper | Android Developers
In other words and in a simple manner, the Main UI DOES have a Message Queue already prepared, and that's why you don't see that error when calling new Handler() within "onCreate, onStart, onResume etc...", but for any worker thread created the system needs a queue to send the messages to when using handlers, although the code doesn't show it, i bet that code is being executed in a worker thread either normal Thread or doInBackground method of an AsyncTask and that's what causes the error, to avoid it remember to always call Looper.prepare before creating a handler from a worker thread.
Hope this Helps.
Regards!
How do you know this is running on the Main thread? And when and where is this getting called from? Instead of creating your handler right before you use it, create it in the onCreate method of your Activity or your Service (depending on what this is).Then in your onDestroy null the value out.

Android Fragments and Separate Threads

I am using the android ViewPager : http://developer.android.com/reference/android/support/v4/view/ViewPager.html
This class allows you to basically slap a bunch of Views or Fragments into a group and page through them easily. My problem occurs when I try to create a separate thread to randomly shuffle through the views.
I extended a thread which would call setCurrentItem on my ViewPager which I passed in through an argument. When I did that I received this:
java.lang.IllegalStateException: Must be called from main thread of process
I figured all I would have to do to fix that would be to call a method from my activityfragment so I created changePageFromActivity to do the dirty work and called that by passing my activity to my thread. But that didn't work either. Below is the full stack trace:
FATAL EXCEPTION: Thread-11
java.lang.IllegalStateException: Must be called from main thread of process
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1392)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:160)
at android.support.v4.view.ViewPager.populate(ViewPager.java:804)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:433)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:405)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:397)
at com.lyansoft.music_visualizer.MusicVisualizerActivity.changePageFromActivity(MusicVisualizerActivity.java:144)
at com.lyansoft.music_visualizer.ShuffleThread.run(ShuffleThread.java:38)
After doing some research I gathered that Fragments are easily destroyed and result in a different thread so to prevent any problems ViewPager just made sure that the method I wanted had to be called from the main activity.
So my question is:
Is it possible to inject something along the lines of
run() { while(condition) { methodIWantHere(); sleep(timeout); } }
inside my main activity's thread without disrupting it?
OR
What is a better design pattern to achieve the effect I would like? (which is to change the view at consistent specified intervals)
A Handler would be an obvious choice.
final Runnable changeView = new Runnable()
{
public void run()
{
methodIWantHere();
handler.postDelayed(this, timeout);
}
};
handler.postDelayed(changeView, timeout);
Try to execute your piece of code by using
runOnUiThread(Runnable action).

MapView and AsyncTask

I am trying to use an AsyncTask class that I created to update a MapView. The problem is I am getting this error when I make my call to execute the AsyncTask:
"Can't create a Handler inside a thread that has not called Looper.prepare()"
I have tried running the Task on the UI Thread using
Handler hand = new Handler(Looper.getMainLooper());
hand.post(new Runnable() {
public void run() {
new RxThread().execute();
}
});
But that just gives me the same error. I realize that my MapView doesn't call looper prepare, and that I'm having troubles getting this to work since I'm running the MapView on a seperate activity rather than the Main Activity. Does anyone have a good solution to this?
IIRC, your error is because you are first referencing AsyncTask on a background thread. You can only create and execute() an AsyncTask on the main application thread.

RuntimeException in AsyncTask

I am using AsyncTask for a long running task but I am getting the following error.
error in doInBackground====java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Why am I getting that error and what does it mean?
You can access GUI only from OnPostExecute and OnProgressUpdate.
You're probably running the task inside a non-UI thread.
The UI thread is set so that it loops. You can see where's the loop in a stack trace or in ddms while debugging:
...
MessageQueue.next() line: 146
Looper.loop() line: 110
...
This loop takes care of handling the messages, like the ones that an AsyncTask sends, with a Handler, like the one the AsyncTask is trying to set. If you're launching the task on a thread that has no looper set you get that message.
Usually this error comes when you change UI from asyntask which is not allowed, other way is to implement handler instead asyntask...
Because you don't post your code, so hard to find issue.
I think because you access UI Thread inDoInBackground. (for example: you access TextView, or Button, or EditText....) This is a most common error when use Asyntask.
you should post some parameter to publishProgress in DoInBackGround. then asyntask will send this param to onProgressUpdate and this method will act on UI Thread

Categories

Resources