2012-02-25 4 views
5

몇 가지 이유로 인해 Android 애플리케이션에서 WebView를 사용해야하고 비즈니스 로직의 일부가 JavaScript에 포함되어 있습니다 (addJavascriptInterface()를 사용하여 실행). 문제는 스크립트에 바인딩 된 객체에서 내 응용 프로그램의 UI 구성 요소를 수정할 수 없다는 것입니다. 설명서에 설명되어 있습니다.Android의 JavaScript에서 UI에 액세스하십시오.

참고 : JavaScript에 바인딩 된 개체는 구성되어있는 스레드가 아닌 스레드에서 실행됩니다.

이 문제의 해결 방법이 있으면 궁금합니다.

답변

13

Handler 인스턴스를 JavaScript 인터페이스에 전달하고 거기에서 실행 파일을 게시하는 데 사용해야합니다. UI 스레드에서이 핸들러가 작성되면 UI 스레드에서 실행 파일 posted there이 호출됩니다.

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

당신이 조각 안쪽에 당신이 당신의 자바 스크립트 인터페이스 코드에서 getActrivity().runOnUIThread(...)을하고 가정을 사용하는 것입니다. WebViewCoreThread가 Javascript 인터페이스 코드를 실행하면 조각이 활동에서 분리되고 getActivity()가 null을 반환하여 NullPointerException이 던져 질 수 있습니다. 이 작업을 수행하는 안전한 방법은 아래 예제와 같이 처리기를 사용하는 것입니다. 또한 Javascript 인터페이스가 실행되기 전에 JavaScript 인터페이스에서 가비지 수집해야하는 경우 ui 구성 요소에 대해 WeakReferences를 사용하는지 확인하십시오.

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"); 
관련 문제