由於某些原因,我必須在我的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