Android/Information

Android ↔ Typescript 함수 공유 방법 (1)

y0ngha 2021. 10. 27. 01:20

이 전에 iOS에서의 방법을 기술한 글이 있는데, 해당 글을 먼저 보고 어떤 상황인지에 대해 참고하며 이 글을 읽으면 된다.

(iOS ↔ Typescript 함수 공유 방법)

 

똑같은 느낌으로 아이디를 저장하거나, 비밀번호를 저장해야한다고 했을 때 사용하는 방법이다.

 

먼저 WebView 하나를 생성해주자.

 

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
    <WebView
            android:visibility="visible"
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
cs

ID가 webView인 WebView 하나를 생성했고, activity의 layout도 정의를 해줬으니 이제 Class딴으로 넘어가자.

 

MainActivity.kt

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
class MainActivity : AppCompatActivity() {
    lateinit var mWebView: WebView
 
    private val webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
 
            CookieManager.getInstance().flush() // Android Cookie Sync Bug Fix
            super.onPageFinished(view, url)
        }
 
        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            if (request != null) {
                if (request.url != null) {
                    val url = request.url.toString()
 
                    view?.clearCache(true) // Android Cookie Sync Bug Fix
                    view?.loadUrl(url)
                    return true
                }
            }
 
            return super.shouldOverrideUrlLoading(view, request)
        }
    }
 
    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.AppTheme)
        super.onCreate(savedInstanceState)
 
        setupListeners()
 
        setContentView(R.layout.activity_main)
 
        if (BuildConfig.DEBUG) {
            WebView.setWebContentsDebuggingEnabled(true)
        }
 
        cookieManager.setAcceptCookie(true) // Android Cookie Sync Bug Fix
 
        mWebView = findViewById(R.id.webView)
 
        this.webViewDefaultSet()
 
        cookieManager.removeSessionCookies() {
            mWebView.clearCache(true)
            mWebView.loadUrl("http://localhost:4200")
            mWebView.addJavascriptInterface(WebViewJsInter(this), "native")
        }
    }
 
    @SuppressLint("SetJavaScriptEnabled")
    private fun webViewDefaultSet() {
        mWebView.settings.javaScriptCanOpenWindowsAutomatically = true                     // 자바스크립트에서 새 창 실행 허용
        mWebView.settings.javaScriptEnabled = true                                        // 자바스크립트 실행 허용
        mWebView.settings.domStorageEnabled = true                                        // 로컬저장소 허용
        mWebView.settings.cacheMode = WebSettings.LOAD_DEFAULT                            // 브라우저 캐시 허용 여부
        mWebView.webChromeClient = WebChromeClient()
        mWebView.webViewClient = webViewClient
        mWebView.settings.displayZoomControls = false                                    // WebView Zoom 허용 여부
        val cookieManager = CookieManager.getInstance()
        cookieManager.setAcceptCookie(true)
        cookieManager.setAcceptThirdPartyCookies(mWebView, true)
    }
}
cs

WebViewJsInter.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class WebViewJsInter(
    private val activity: MainActivity
) {
 
    private val sharedPreferencesService = SharedPreferencesService(activity)
 
    @JavascriptInterface
    fun getPref(key: String, defaultData: String): String {
        return this.sharedPreferencesService.getStringPreferences(key, defaultData)
    }
 
    @JavascriptInterface
    fun setPref(key: String, data: String) {
        this.sharedPreferencesService.setStringPreferences(key, data)
    }
}
 
cs

먼저 소스를 설명하기 전, Android에서 WebView를 이용하여 특정 Web을 띄운 후 해당 Web에서 Cookie 조작을 하게 될 경우 이슈가 있다.

해당 부분을 처리하기 위해 webViewClient를 따로 선언한다던지, 혹은 CookieManager Class를 불러와서 여러가지 작업들을 진행하고 있는데 본인이 만약 Cookie를 많이 쓰지 않는다 라고 하면 선언할 필요 없다.

(* Android WebView Cookie Issue)

 

또 한 현재 기술한 소스의 자바 버전은 JAVA 11버전인데, MainActivity.kt의 41번째 Line을 보면 잘못된 방법으로 WebView를 찾아오고 있는 것이 보인다.

(JAVA 11버전부터는 Android Data Binding을 기본적으로 지원해주고 있기 때문에 findViewById()를 사용하지 않고도 작성할 수 있다.

해당 부분에 대해서는 후에 기술하도록 한다.)

 

이어서, 소스를 설명하자면 가장 핵심적인 부분의 줄은 48번째 Line이다.

addJavascriptInterface 함수를 이용하게 되면, @JavascriptInterface Annotation이 되어있는 함수들을 Javascript상에 추가할 수 있는 함수다.

(window Object 안에 들어가게 된다.)

후에 나오는 "native"는 window Object 안에 어떤 이름으로 넣을 것 인가에 대해 작성하는 부분이다.

(위와 같은 경우에는 @JavascriptInterface Annotation이 되어있는 함수를 부르기 위해선, Javascript에서 window.native.(함수명) 으로 작성하면 된다.)

 

Android에서 Application 내부에 값을 저장하려면 *SharedPreferences를 이용해서 접근하면 된다.

(* SharedPreferences → XML 파일에 값을 저장하는 데 사용. 이러한 파일은 Android에서 생성, 유지 관리 및 삭제. 암호화되지 않음)

 

위와 같이 함수를 구성하면, 일단 Android Native에서의 설계는 끝났다.

이 후 TypeScript에 작성해야하는 부분은 이 후에 기술하도록 하겠다.