在安卓设备上从JavaScript访问用户界面

6
出于某些原因,我不得不在我的Android应用程序中使用WebView,并且业务逻辑的一部分包含在JavaScript中(我使用addJavascriptInterface()运行它)。问题是我不能从绑定到脚本的对象修改应用程序的UI组件。文档中已经解释了原因:
注意:绑定到您的JavaScript的对象在另一个线程中运行,而不是在构造它的线程中运行。
我想知道是否有解决这个问题的方法?
2个回答

18

您需要将 Handler 实例传递给 JavaScript 接口,并使用它在其中发布可运行项。如果此处理程序在 UI 线程上创建,则发布的可运行项也将在 UI 线程上调用

Handler mHandler = new Handler(); // must be created on UI thread, e.g. in Activity onCreate

// from javascript interface...
mHandler.post(new Runnable() {
    @Override
    public void run() {
        // code here will run on UI thread
    }
});

另一个解决方法是使用 ActivityrunOnUiThread 方法。

mActivity.runOnUIThread(new Runnable() {
    @Override
    public void run() {
       // code here will run on UI thread
    }
});

你可以始终使用new Handler(Looper.getMainLooper())来让 Handler 使用 UI 线程。 - ImMathan

1
假设您在片段内部,并且在JavaScript接口代码中执行getActrivity().runOnUIThread(...)。当WebViewCoreThread执行JavaScript接口代码时,片段可能已从活动中分离,getActivity()将返回null,导致抛出NullPointerException。安全的方法是使用处理程序,如下面的示例所示。此外,请确保JavaScript接口对ui组件使用WeakReferences,以防它们在执行JavaScript接口之前被垃圾回收。
 myWebView.addJavascriptInterface(new Object() {
        private Handler handler = new Handler();
        private WeakReference<ProgressBar> progressBarRef = new WeakReference<ProgressBar>(
                myWebViewProgressBar);
        private WeakReference<WebView> myWebViewRef = new WeakReference<WebView>(
                myWebView);

        @SuppressWarnings("unused")
        public void onFirstImageLoad() {

            handler.post(new Runnable() {
                @Override
                public void run() {
                    ProgressBar progressBar = progressBarRef.get();
                    WebView webView = myWebViewRef.get();
                    if (progressBar != null) {
                        progressBar.setVisibility(View.GONE);
                    } 
                    if (webView != null) {
                        webView .setVisibility(View.VISIBLE);
                    }
                }
            });
        }
    }, "jsInterface");

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