I am writing an android app in which i insert javascript code in a webview and then the javascript replies by calling a java method specified with webview.addJavascriptInterface
.
The problem is that the javascript-callback is running in another thread than the original view from which i started the process. Because of that i cant access the original view.
How can i access the original view?
I am using api level 7.
Here are the important code fragments:
JavaScript call:
webview.addJavascriptInterface(this, "ACall");
webview.loadUrl("javascript: ACall.update();");
Callback:
public void update() {
TextView tv = (TextView) findViewById(R.id.tv);
Log.v("test", "test");
tv.setText("test");
}
And the stacktrace:
Uncaught handler: thread WebViewCoreThread exiting due to uncaught exception
ndroid.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRoot.checkThread(ViewRoot.java:2706)
at android.view.ViewRoot.requestLayout(ViewRoot.java:560)
at android.view.View.requestLayout(View.java:7918)
at android.view.View.requestLayout(View.java:7918)
at android.view.View.requestLayout(View.java:7918)
at android.view.View.requestLayout(View.java:7918)
at android.view.View.requestLayout(View.java:7918)
at android.widget.TextView.checkForRelayout(TextView.java:5380)
at android.widget.TextView.setText(TextView.java:2684)
at android.widget.TextView.setText(TextView.java:2552)
at android.widget.TextView.setText(TextView.java:2527)
at shylux.android.GameActivity.update(GameActivity.java:53)
at android.webkit.BrowserFrame.stringByEvaluatingJavaScriptFromString(Native Method)
at android.webkit.BrowserFrame.stringByEvaluatingJavaScriptFromString(Native Method)
at android.webkit.BrowserFrame.loadUrl(BrowserFrame.java:149)
at android.webkit.WebViewCore.loadUrl(WebViewCore.java:1449)
at android.webkit.WebViewCore.access$1400(WebViewCore.java:48)
at android.webkit.WebViewCore$EventHub$1.handleMessage(WebViewCore.java:890)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:611)
at java.lang.Thread.run(Thread.java:1096)
//////////////// Current solution:
This is my current solution. I think there have to be a better way. This requires a lot of work if you want to do different tasks.
public void update() {
tv.post(new UpdateTask());
}
private class UpdateTask implements Runnable {
public void run() {
tv.setText("test");
}
}
Thanks, I had a similar problem.
The solution with runOnUiThread
was surprisingly simple.
You can not update the UI of the activity from outside the thread in which it was originally created. runOnUiThread()
method is used for doing UI changes.
runOnUiThread(new Runnable() {
@Override
public void run() {
button.setBackgroundResource(R.drawable.practice_ri_wrong_3);
}
});
runOnUiThread is your friend. Just cook up a Runnable that makes the changes you need to your view, and pass it to runOnUiThread. The painless threading article suggests some other options you might consider (if you don't have a handle on the activity, then tv.post might be a goer).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With