Wrong Thread Exception - android

whenever I am using
listview.scrollTo(int x,int y) method I am getting an Exception called
android.view.View Root Implementation Called From Wrong Thread Exception: only the original thread that created a hierarchy can touch its views.
May I know what is the problem and what is the solution for this exception?

To update the listview, you need to update it from the main thread. You can throw the information to the main thread and update it, using a Handler.

Related

IllegalStateException when updating adapter data

Please, help me to find a fix for this bug, where it appears in the production version and I don't know where is the bug exactly from the following log.
I got the following log report from Crashlytics:
ListView.java line 1557
android.widget.ListView.layoutChildren
Fatal Exception: java.lang.IllegalStateException: The content of the
adapter has changed but ListView did not receive a notification. Make sure
the content of your adapter is not modified from a background thread, but
only from the UI thread. [in ListView(2131558802, class
android.widget.ListView) with Adapter(class
android.widget.HeaderViewListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1557)
at android.widget.AbsListView.onTouchEvent(AbsListView.java:3442)
at android.view.View.dispatchTouchEvent(View.java:7565)
.
.
.
You can only change the data from the main thread.
If you are getting data in a background thread, either wait for the result in the main thread, change the data, and call adapter.notifyDataSetChanged(), or go back to the main thread from your background thread using a handler and a run() method.

Is it okay to read data from UI elements in another thread?

I just found out that some of my code is (unindentionally) running in a worker thread and reads some data from UI elements:
e.g. checkbox.isChecked(), textView.getText()
and to my surprise, this works just fine...
I expected that it would crash with an exception (like the following exception that I get when I want to write to UI elements):
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
According to the Android docs:
Only objects running on the UI thread have access to other objects on
that thread. Because tasks that you run on a thread from a thread pool
aren't running on your UI thread, they don't have access to UI
objects.
So, is it really okay to read data from UI elements from other threads?
If not: why is there no exception?
is it really okay to read data from UI elements from other threads?
No, but not for the reasons that you may be thinking.
First, as soon as you fork the background thread, the user might press BACK or otherwise do something that destroys your activity. It is not safe to try to use widgets of a destroyed activity.
Second, there is little to no thread synchronization logic in the View class or its subclasses. The main application thread may be modifying the data at the same time that you are trying to use it, resulting in possible concurrency issues.
I would pass the data from the widgets into the thread (e.g., thread constructor).
why is there no exception?
AFAIK, that specific exception is only thrown on setters or other things that modify the contents of the widget. This does not mean that any code that does not raise that exception is guaranteed to be safe.
You can't redraw (invalidate) your Views outside main thread which is also UI thread. Setting text for TextView also causes redrawing view ofc... But getting text just returns String (or Editable?), so its working...
Note that there are some other restrictions and limitations, e.g. when you pass EditText to some AsyncTask, but while it's working the main Activity (holding passed view) finish then you might get NPE, because view is also gone... In this and similar cases WeakReferences are very usefull

getting sporadic ViewRoot$CalledFromWrongThreadException

I have an app with a long running action. I am using AsyncTask. In its onPostExecute() I call a function that modifies some views. I am getting this error on calling setEnabled on the 5th view of 10 views being modified. And it happens very seldom, getting the odd error report from users.
Obviously a multithreading issue. But I thought onPostExecute() always runs on the UI thread? Could it be that the UI thread suddenly gets changed to another thread??
Stack Trace:
generated the following exception:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original
thread that created a view hierarchy can touch its views.
--------- Instruction Stack trace ---------
android.view.ViewRoot.checkThread(ViewRoot.java:3041)
android.view.ViewRoot.invalidateChild(ViewRoot.java:647)
android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:673)
android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
android.view.View.invalidate(View.java:5255)
android.view.View.invalidateDrawable(View.java:7293)
android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:300)
8.
android.graphics.drawable.DrawableContainer.selectDrawable(DrawableContainer.java:227)
9.
android.graphics.drawable.StateListDrawable.onStateChange(StateListDrawable.java:99)
android.graphics.drawable.Drawable.setState(Drawable.java:400)
android.view.View.drawableStateChanged(View.java:7374)
android.view.ViewGroup.drawableStateChanged(ViewGroup.java:3357)
android.widget.FrameLayout.drawableStateChanged(FrameLayout.java:164)
android.view.View.refreshDrawableState(View.java:7388)
android.view.View.setEnabled(View.java:3147)
com.voltup.powermax.ac.a(ActivityAppUiProxy.java:383)
com.voltup.powermax.cp.onPostExecute(ModeChange.java:1)
android.os.AsyncTask.finish(AsyncTask.java:417)
But I thought onPostExecute() always runs on the UI thread?
Yes, it does. Per Selvin's comment, AFAIK, if you try to create an AsyncTask from another thread, it fails.
Could it be that the UI thread suddenly gets changed to another thread??
No. More likely, you are accidentally going down a code path in doInBackground() that is updating the UI.
If you have a full stack trace showing that you are getting this exception from logic executed in onPostExecute(), please edit your question and paste in that stack trace.

Creating a new object from Android update() loop

I am trying to create an Android game, but am running into trouble with one part. I started with the Android LunarLander example project, so instead of pasting my confusing code, I will just identify the relevant section in the sample code. In the updatePhysics method, I try to create a new FlyingObject (a class I created). I receive this error for the line where I try to create the FlyingObject:
E/AndroidRuntime(201): Uncaught handler: thread Thread-9 exiting due to uncaught exception
E/AndroidRuntime(201): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I have Googled around, and cannot figure out how I can dynamically create objects in my game.
Any help would be greatly appreciated. Thanks!
Well this error mostly comes when you are trying to Update the UI from a Non-UI thread. So, probably use Handler or runOnUiThread() to update your UI thread from a Non-UI thread.

problem with calling invalidate in async task thread in Android !

I am trying to call the invalidate() from asyntask thread. I am getting this error :
10-18 15:14:30.469: ERROR/AndroidRuntime(889): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
The line I have used is :
mainClass.myMapView.invalidate();//where mainClass=main UI class
Can anyone kindly suggest where my fault is ?
Thanks.
-
ahsan
You can't do anything UI-related from a different thread than the UI thread (thus its name). You should call invalidate() in either onPostExecute() or in onProgress(). Or, use runOnUiThread() (which is basically what publishProgress() / onProgress() does).

Categories

Resources