[    스프링과 안드로이드 연동5 : Javascript에서 Android 함수를 호출하기    ]



요즘은 웹을 개발하고 웹뷰를 이용해서 안드로이드에 붙이는 식으로 해서 반응형으로 하이브리드 앱을 만드는 경우가 많은데,


이러한 경우 웹뷰에서 버튼을 클릭한다거나 했을 때 자바스크립트에서 안드로이드에 있는 함수를 호출해서 


안드로이드를 제어하고 싶은 경우가 있다.


----------------------------------------------------------------------------------------------------------------------------------


먼저, 웹뷰를 연결해 세팅부터 하자.


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);
 
        // 로드할 주소를 입력
        webView1.loadUrl("http://192.168.0.8:8080/");
</span>

일단 스프링 웹 프로젝트에서 작성한 웹 페이지를 띄우는 웹뷰를 작성한다.

그 다음에 


2. 자바스크립트에서 호출시 수행할 안드로이드 메서드를 작성한다.


이때, 자바스크립트와 안드로이드를 중간에서 인터페이스 역할을 할 클래스를 작성해서 그 내부에

메서드를 정의하도록 한다.


당연히 인터넷 작업을 해야함으로

<!-- 인터넷 접속 권한 추가 -->
<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);
 
        // 로드할 주소를 입력
        webView1.loadUrl("http://192.168.0.8:8080/");
 
        // 텍스트 뷰 위젯 연결
        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>



3. 만들어준 JavascriptInterface 클래스를 웹뷰에 등록해 주어야 한다.


1
2
3
<span style="font-size: 14pt;">
webView1.addJavascriptInterface(new JavascriptInterface(),"myJSInterfaceName");
</span>

이때 중요한 점은 

webView1.addJavascriptInterface(new JavascriptInterface(),"myJSInterfaceName");

에서 두번째 매개변수란에 myJSInterfaceName 처럼 인터페이스 이름을 지정하게 되어 있는데

이 이름을 이용해서 자바스크립트에서 호출하게 된다.



4. 스프링 웹 프로젝트의 자바스크립트에서 특정 이벤트 발생시 안드로이드 함수를 호출하는 구문을 작성하자.


가장 중요한 부분은 window.myJSInterfaceName.callMethodName(str); 부분이다.

window.(지정한 javascript인터페이스명).수행할메서드명() 으로 호출하게 된다.

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);
 
        // 로드할 주소를 입력
        webView1.loadUrl("http://192.168.0.8:8080/");
 
        // 텍스트 뷰 위젯 연결
        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);
                }
            });
        }
    }
 
}

+ Recent posts