5

我正在编写一个 android 应用程序,在其中我在 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");
    }
}
4

2 回答 2

5

谢谢,我也有类似的问题。解决方案runOnUiThread非常简单。

您无法从最初创建活动的线程外部更新活动的 UI。runOnUiThread()方法用于进行 UI 更改。

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                button.setBackgroundResource(R.drawable.practice_ri_wrong_3);
            }
        });
于 2012-06-21T11:01:07.770 回答
2

runOnUiThread是你的朋友。只需编写一个可对视图进行所需更改的 Runnable,然后将其传递给 runOnUiThread。无痛线程文章提出了一些您可能会考虑的其他选项(如果您没有处理活动,那么 tv.post 可能是一个观众)。

于 2012-05-25T14:42:55.837 回答