由于某些原因,我必须在我的Android应用程序中使用WebView,并且业务逻辑的一部分包含在JavaScript中(我使用addJavascriptInterface()运行它)。问题是我无法从绑定到脚本的对象修改我的应用程序的UI组件。这是在文档中解释说:Android上的JavaScript访问UI
注:绑定到你的JavaScript运行在另一个线程 ,而不是在它构建了线程的对象。
我想知道是否有解决此问题的一些解决方法?
由于某些原因,我必须在我的Android应用程序中使用WebView,并且业务逻辑的一部分包含在JavaScript中(我使用addJavascriptInterface()运行它)。问题是我无法从绑定到脚本的对象修改我的应用程序的UI组件。这是在文档中解释说:Android上的JavaScript访问UI
注:绑定到你的JavaScript运行在另一个线程 ,而不是在它构建了线程的对象。
我想知道是否有解决此问题的一些解决方法?
您需要将Handler实例传递给您的JavaScript接口并使用它将信息发布到那里。如果此处理程序将在UI线程上创建,则runnables posted there也将在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
}
});
另一种解决方法是使用Activity
的方法runOnUIThread
mActivity.runOnUIThread(new Runnable() {
@Override
public void run() {
// code here will run on UI thread
}
});
假设你是一个片段内,你在你的JavaScript界面代码做getActrivity().runOnUIThread(...)
。有可能在WebViewCoreThread执行JavaScript接口代码时,片段与活动分离,并且getActivity()将返回null,从而导致引发NullPointerException。一个安全的方法是使用一个Handler,如下例所示。另外,确保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");
非常感谢!这确实有一招:) – 2012-02-25 23:20:13
您可以随时使用'new Handler(Looper.getMainLooper())'使Handler使用UI线程。 – ImMathan 2016-10-28 12:29:32