2013-02-25 2 views
2

기본 응용 프로그램에서 WebView과 많은 JavaScript를 사용하고 있습니다. JS 측에서 네이티브 함수를 호출하려고한다면 JavaScriptInterface을 사용하면 다소 부드럽습니다. 그러나 네이티브가 JS 함수를 호출하기를 원한다면 그렇게 쉽지는 않습니다. 지금까지 두 가지 솔루션을 시도했다 :WebView와 네이티브 간의 통신을위한 대체 방법

  • loadUrl 방법 URL javascript:something()과 전화 - 기능 모든 x 초 네이티브 측의 요청 기능 실행
  • 후 숨기고 사용자가 키보드 WebView에 뭔가를 입력 할 때부터 허용되지 않음 (String 개체로 표시) 및 을 호출하면 결과에 eval()가 표시됩니다. 간혹 1 초 간격을 설정 한 후 50-60 초 후에 요청을 받았습니다.

이 통신 모델을 수행하는 다른 방법이 있는지 궁금합니다. 앱 내에 로컬 Socket/HTTP/something-else 서버를 생성하고 WebView에 대한 액세스 권한을 부여한다고 가정 해 보겠습니다. 나는 그것이 가능하다면 어떤 조언을 찾고있다.

답변

3

자바 리플렉션을 사용하여 자바에서 자바 스크립트를 호출하는 다음 코드를 작성했습니다. 다음과 같은 loadUrl 버그를 피할 수 있습니다. 1. 입력에 포커스가있을 때 loadUrl이 키보드를 숨길 수 있습니다. 2. loadUrl을 너무 자주 호출 할 수 없습니다. 내가 다른 통신 모델 작업을 진행하는 방법을 모른다

public class AdvancedWebView extends WebView { 
    private static final int EXECUTE_JS = 194; 
    Method sendMessageMethod; 
    Object webViewCore; 
    boolean initFailed = false;; 
    InputMethodManager imm; 


    public AdvancedWebView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 
     this.getSettings().setJavaScriptEnabled(true); 
     this.initReflection(); 
    } 

    @SuppressWarnings("rawtypes") 
    private void initReflection() { 
     Object webViewObject = this; 
     Class webViewClass = WebView.class; 
     try { 
      Field f = webViewClass.getDeclaredField("mProvider"); 
      f.setAccessible(true); 
      webViewObject = f.get(this); 
      webViewClass = webViewObject.getClass(); 
     } catch (Throwable e) { 
      // mProvider is only required on newer Android releases. 
     }  

     try { 
      Field f = webViewClass.getDeclaredField("mWebViewCore"); 
      f.setAccessible(true); 
      webViewCore = f.get(webViewObject); 
      if (webViewCore != null) { 
       sendMessageMethod = webViewCore.getClass().getDeclaredMethod("sendMessage", Message.class); 
       sendMessageMethod.setAccessible(true);  
       System.out.println("sendMessageMethod-----"+sendMessageMethod); 
      } 
      hasIntercepted = true; 
     } catch (Throwable e) { 
      hasIntercepted = false; 
      //Log.e(LOG_TAG, "PrivateApiBridgeMode failed to find the expected APIs.", e); 
     }finally{ 
      if(sendMessageMethod == null) 
      { 
       hasIntercepted = false; 
      } 
     } 
    } 

    private void loadJs(String url) { 
     if (sendMessageMethod == null && !initFailed) { 
      initReflection(); 
     } 
     // webViewCore is lazily initialized, and so may not be available right away. 
     if (sendMessageMethod != null) { 
      //String js = popAndEncodeAsJs(); 
      Message execJsMessage = Message.obtain(null, EXECUTE_JS, url); 
      try { 
       sendMessageMethod.invoke(webViewCore, execJsMessage); 
      } catch (Throwable e) { 
       //Log.e(LOG_TAG, "Reflection message bridge failed.", e); 
      } 
     } 
    } 
} 
+0

는 private void loadJs를 변경해야합니다. -> public void loadJs; 자바 스크립트를 호출하려면 webview.loadUrl 대신 webview.loadJs를 사용하십시오. – o0omycomputero0o

관련 문제