2012-02-25 14 views
5

何らかの理由で、AndroidアプリケーションでWebViewを使用しなければならず、ビジネスロジックの一部がJavaScriptに含まれています(addJavascriptInterface()を使用して実行します)。問題は、スクリプトにバインドされたオブジェクトからアプリケーションのUIコンポーネントを変更できないことです。これは、マニュアルに記載されているだ:AndroidのJavaScriptからUIにアクセスする

注:それが構築されたスレッド内で別の のスレッドで実行されていない、あなたはJavaScriptにバインドされたオブジェクトを。

この問題の回避策があるのでしょうか?

答えて

13

JavaScriptインターフェイスにHandlerインスタンスを渡して、そこにランナビリティをポストする必要があります。このハンドラがUIスレッドで作成される場合、実行可能ファイル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 
    } 
}); 
+1

ありがとうございます!これはやったよ:) –

+0

ハンドラにUIスレッドを使用させるには、 'new Handler(Looper.getMainLooper())'をいつでも実行できます。 – ImMathan

1

を使用することですあなたがフラグメント内であり、あなたがあなたのJavascriptのインタフェースコードでgetActrivity().runOnUIThread(...)をやっていると仮定します。 WebViewCoreThreadがJavascriptインターフェイスコードを実行するときに、そのフラグメントはアクティビティから切り離され、getActivity()はnullを返し、結果としてNullPointerExceptionがスローされることがあります。これを行うための安全な方法は、以下の例のようにHandlerを使用することです。また、Javascriptインターフェイスが実行される前にガベージコレクションされる必要がある場合、JavaScriptインターフェイスがUIコンポーネントのWeakReferenceを使用するようにしてください。

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"); 
関連する問題