요즘은 웹을 개발하고 웹뷰를 이용해서 안드로이드에 붙이는 식으로 해서 반응형으로 하이브리드 앱을 만드는 경우가 많은데,
이러한 경우 웹뷰에서 버튼을 클릭한다거나 했을 때 자바스크립트에서 안드로이드에 있는 함수를 호출해서
안드로이드를 제어하고 싶은 경우가 있다.
----------------------------------------------------------------------------------------------------------------------------------
먼저, 웹뷰를 연결해 세팅부터 하자.
1. [ WebView(웹뷰) 세팅 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span style= "font-size: 14pt;" > / 웹뷰 위젯 연결 webView1 = (WebView)findViewById(R.id.webView1); // 클리기 새창 안뜨게... webView1.setWebViewClient( new WebViewClient()); // 세부 세팅객체 가져오기 WebSettings mWebSettings = webView1.getSettings(); // 자바스크립트 사용 허용 // 웹뷰 내에서 자바스크립트 실행해 자바스크립트에서 안드로이드 함수 // 실행시킬려면 필수로 세팅필요 mWebSettings.setJavaScriptEnabled( true ); // 안드로이드에서 제공하는 줌 아이콘을 사용할 수 있도록 설정 mWebSettings.setBuiltInZoomControls( true ); // 캐시 사용 여부 설정 mWebSettings.setAppCacheEnabled( false ); // 로드할 주소를 입력 </span> |
<!-- 인터넷 접속 권한 추가 -->
<uses-permission android:name="android.permission.INTERNET" />
를 manifest에 추가해주어야 하고
네트워크 작업은 백그라운드 쓰레드로 해야하며
백그라운드 쓰레드에서는 메인 뷰의 화면 제어를 할 수 없음으로
handler에게 대신해달라고 요청을 해야한다.
앞에선 계속 그렇게 해왔는데 이 2가지를 한번에 하는 것이
handler.post(new Runnable(){ run() }) 을 이용한 방식이다.
이런식으로해서 JavascriptInterface 클래스를 만들도록 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | <span style= "font-size: 14pt;" > package com.example.kscs.androidspringconnection1; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.TextView; public class WebViewActivity extends AppCompatActivity { WebView webView1; Handler handler = new Handler(); TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); // 웹뷰 위젯 연결 webView1 = (WebView)findViewById(R.id.webView1); // 클리기 새창 안뜨게... webView1.setWebViewClient( new WebViewClient()); // 세부 세팅객체 가져오기 WebSettings mWebSettings = webView1.getSettings(); // 자바스크립트 사용 허용 // 웹뷰 내에서 자바스크립트 실행해 자바스크립트에서 안드로이드 함수 // 실행시킬려면 필수로 세팅필요 mWebSettings.setJavaScriptEnabled( true ); // 안드로이드에서 제공하는 줌 아이콘을 사용할 수 있도록 설정 mWebSettings.setBuiltInZoomControls( true ); // 캐시 사용 여부 설정 mWebSettings.setAppCacheEnabled( false ); // 로드할 주소를 입력 // 텍스트 뷰 위젯 연결 textView = (TextView)findViewById(R.id.textView); } final class JavascriptInterface { @android .webkit.JavascriptInterface // 최근에는 이 어노테이션을 붙여줘야 동작하게 되어 있다.. public void callMethodName( final String str){ // 반드시 final이어야 한다. // 네트워크를 통한 작업임으로 백그라운드 스레드를 써서 작업해야한다. // 또한, 백그라운드 스레드는 직접 메인 뷰에 접근해 제어할 수 없음으로 // 핸들러를 통해서 작업해야하는데 // 이 때문에 한번에 handler.post()를 통해서 내부에 Runnable을 구현해 작업한다. handler.post( new Runnable() { @Override public void run() { // handle를 통해서 화면에 접근하는 것임으로 가능함 textView.setText( "자바스크립트에서 전달받은 문자열을 쓴다 : " + str); } }); } } } </span> |
1 2 3 | <span style= "font-size: 14pt;" > webView1.addJavascriptInterface( new JavascriptInterface(), "myJSInterfaceName" ); </span> |
function
callAndroid(){
var
str = document.getElementById("txtName").value;
window.myJSInterfaceName.callMethodName(str);
}
<
form
id
=
"formName"
action
=
""
>
<
input
id
=
"txtName"
type
=
"text" /
>
<
button
onclick
=
"javascript:callAndroid()"
>호출하기</
button
>
</
form
>
1 2 3 4 5 6 7 8 9 10 11 12 | <span style= "font-size: 14pt;" > function callAndroid(){ var str = document.getElementById( "txtName" ).value; window.myJSInterfaceName.callMethodName(str); } <form id= "formName" action= "" > <input id= "txtName" type= "text" /> <button onclick= "javascript:callAndroid()" >호출하기</button> </form> </span> |
여기까지 했다면,
웹뷰 상에서 안드로이드 사용자가 "호출하기" 버튼을 클릭시에 callAndroid() 자바스크립트 메서드가 수행되고
해당 자바스크립트 메서드에서 window.myJSInterfaceName.callMethodName(str); 을 통해 안드로이드 메서드를
호출하여, TextView에 있는 메시지를 웹뷰를 통해 입력한 값으로 세팅하게 된다.
안드로이드 쪽 전체 코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | package com.example.kscs.androidspringconnection1; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.webkit.JavascriptInterface; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.TextView; public class WebViewActivity extends AppCompatActivity { WebView webView1; Handler handler = new Handler(); TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); // 웹뷰 위젯 연결 webView1 = (WebView)findViewById(R.id.webView1); // 클리기 새창 안뜨게... webView1.setWebViewClient( new WebViewClient()); // 세부 세팅객체 가져오기 WebSettings mWebSettings = webView1.getSettings(); // 자바스크립트 사용 허용 // 웹뷰 내에서 자바스크립트 실행해 자바스크립트에서 안드로이드 함수 // 실행시킬려면 필수로 세팅필요 mWebSettings.setJavaScriptEnabled( true ); // 안드로이드에서 제공하는 줌 아이콘을 사용할 수 있도록 설정 mWebSettings.setBuiltInZoomControls( true ); // 캐시 사용 여부 설정 mWebSettings.setAppCacheEnabled( false ); // 로드할 주소를 입력 // 텍스트 뷰 위젯 연결 textView = (TextView)findViewById(R.id.textView); webView1.addJavascriptInterface( new JavascriptInterface(), "myJSInterfaceName" ); } final class JavascriptInterface { @android .webkit.JavascriptInterface public void callMethodName( final String str){ // 반드시 final이어야 한다. // 네트워크를 통한 작업임으로 백그라운드 스레드를 써서 작업해야한다. // 또한, 백그라운드 스레드는 직접 메인 뷰에 접근해 제어할 수 없음으로 // 핸들러를 통해서 작업해야하는데 // 이 때문에 한번에 handler.post()를 통해서 내부에 Runnable을 구현해 작업한다. handler.post( new Runnable() { @Override public void run() { // handle를 통해서 화면에 접근하는 것임으로 가능함 textView.setText( "자바스크립트에서 전달받은 문자열을 쓴다 : " + str); } }); } } |