安卓WebView中的JavaScript回调原视图

5

我正在编写一款安卓应用,在其中我在一个webview中插入javascript代码,然后javascript通过调用指定的java方法来回复,该方法是使用webview.addJavascriptInterface指定的。

问题是:javascript回调在另一个线程中运行,而不是我开始进程的原始视图所在的线程。因此,我无法访问原始视图。

如何访问原始视图?

我正在使用API 7。

以下是重要的代码片段:

JavaScript 调用:

webview.addJavascriptInterface(this, "ACall");
webview.loadUrl("javascript: ACall.update();");

回调函数:

public void update() {
    TextView tv = (TextView) findViewById(R.id.tv);
    Log.v("test", "test");
    tv.setText("test");
}

并且还有堆栈跟踪:

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)

//////////////// 现有解决方案:

这是我的现有解决方案。我认为一定有更好的方法。如果您想执行不同的任务,这需要大量的工作。

public void update() {
    tv.post(new UpdateTask());
}

private class UpdateTask implements Runnable {
    public void run() {
        tv.setText("test");
    }
}
2个回答

5
谢谢,我有类似的问题。 使用runOnUiThread解决方案非常简单。
在创建活动的线程之外,您无法更新活动的UI。使用runOnUiThread()方法进行UI更改。
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                button.setBackgroundResource(R.drawable.practice_ri_wrong_3);
            }
        });

2

runOnUiThread是你的好朋友。只需创建一个Runnable对象,对视图进行所需更改,并将其传递给runOnUiThread即可。如果您不了解活动,则无痛线程处理文章提供了其他一些选项(然后tv.post可能会起作用)。


好的,我已经成功运行了它。但正如我之前写的那样,希望有更好的解决方案。也许已经有这样的类了?我会认真阅读无痛线程文章,希望能找到一些有用的东西。 - Shylux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接