Title says it all. Well mostly. This is only happening on 1 device. Other devices are fine.
In the onPostExecute
of a AsyncTask
I am calling the code below, before getting this exception I did not have the runOnUiThread
, the runnable was added because I am getting the CalledFromWrongThreadException exception.
EDIT
Here is what I have discovered. In certain circumstances an application can have more than one "looper" and therefore more than one "UI thread".
Since an application can have more than one "UI thread" and an AsyncTask always "Runs on the UI thread" [ref], someone decided [poorly] that instead of the AsyncTask always running on its creation thread (which in 99.999999% of cases would be the correct "UI thread") they decided to use hocus pocus (or a poorly crafted shortcut, you decide) to execute on the "main looper"..
Android: got CalledFromWrongThreadException in onPostExecute() - How could it be?
So it seems now I need to find a way to make sure the async tasks thread is always the looper thread the app is on :(
getParentActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
setAdapterData(result);
}
});
when that didn't work I tried this as well, and tried them together.
lvUpdatesList.post(new Runnable()
{
@Override
public void run()
{
lvUpdatesList.setAdapter(updateListAdapter);
}
});
I am super confused as to why it is behaving like this.
07-03 13:19:51.908: E/AndroidRuntime(4479): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.view.View.invalidate(View.java:5279)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.widget.AbsListView.resetList(AbsListView.java:1120)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.widget.ListView.resetList(ListView.java:511)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.widget.ListView.setAdapter(ListView.java:440)
07-03 13:19:51.908: E/AndroidRuntime(4479): at com.********.********.FragmentUpdates.setAdapterData(FragmentUpdates.java:213)
07-03 13:19:51.908: E/AndroidRuntime(4479): at com.********.********.FragmentUpdates$AsyncGetUpdates.onPostExecute(FragmentUpdates.java:185)
07-03 13:19:51.908: E/AndroidRuntime(4479): at com.********.********.FragmentUpdates$AsyncGetUpdates.onPostExecute(FragmentUpdates.java:1)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.AsyncTask.finish(AsyncTask.java:417)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.AsyncTask.access$300(AsyncTask.java:127)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.Handler.dispatchMessage(Handler.java:99)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.Looper.loop(Looper.java:130)
07-03 13:19:51.908: E/AndroidRuntime(4479): at android.os.HandlerThread.run(HandlerThread.java:60)
full asynctask
class AsyncGetUpdates extends AsyncTask<Void, Void, List<UpdateDTO>>
{
String userId;
@Override
protected void onPreExecute()
{
showDialog();
userId = getParentActivity().getCurrentUser().getUser_id();
super.onPreExecute();
}
@Override
protected List<UpdateDTO> doInBackground(Void... params)
{
boolean followingOnly = false;
if (myState == MyState.Following)
followingOnly = true;
return APIHelper.getUpdates(userId, followingOnly, count);
}
@Override
protected void onPostExecute(final List<UpdateDTO> result)
{
killDialog();
isCurrentlyUpdating = false;
getParentActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
setAdapterData(result);
}
});
super.onPostExecute(result);
}
}