Android ↔ Typescript 함수 공유 방법 (1)
이 전에 iOS에서의 방법을 기술한 글이 있는데, 해당 글을 먼저 보고 어떤 상황인지에 대해 참고하며 이 글을 읽으면 된다.
똑같은 느낌으로 아이디를 저장하거나, 비밀번호를 저장해야한다고 했을 때 사용하는 방법이다.
먼저 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에 작성해야하는 부분은 이 후에 기술하도록 하겠다.