안드로이드
[Android] WebView 에서 bridge(@javascriptIngerface)를 구현
IT꿈나무
2023. 1. 5. 19:00
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
Bridge 란?
브릿지의 사전적 정의는 '다리'이다. 웹뷰 상에서 다리는 웹과 네이티브 간의 다리 역할을 하는 것을 의미 한다.
다시 말해 웹이 네이티브를 제어하기 위하여 웹뷰가 @javascriptInterface를 통해서 네이티브의 코드를 직접 제어 하는 interface를 말한다.
목적:
WebView 환경에서 Web과 native간의 데이터를 주고 받기 위한 bridge(@javascriptInterface)를 구현한다.
- 1. Web에서 native로 데이터를 전달해 보는 코드를 구현해 본다. (hello Android)
- 2. native에서 web로 데이터를 전달해 보는 코드를 구현해 본다. (Hello JavaScript)
- % web 자원은 assets에 적용하시오.
note: assets의 정의는 '자산'이라고 하며 apk 내에서 필요한 리소스를 배포해야 할때 사용된다.
<sampleWebView.html>
<html>
<head>
<meta charset="utf8">
<script type="text/javascript">
webCallback = function(str){
console.log("webCallback "+ str);
alert("webCallback "+ str);
}
</script>
</head>
<body>
<center><h1>샘플 웹 사이트</h1></center>
<input type="button" value="webCallback('웹에서 로그 전달') 함수 호출" onclick="window.webCallback('웹에서 로그 전달')"/> <br>
<br>
Android(aos) 호출 관련 (bridge는 aos)
<br>
<input type="button" value="aos.pluginLog('Hello Android') 함수호출" onclick="window.aos.pluginLog('Hello Android')"/> <br>
</body>
</html>
<Bridge.java>
package com.jky.mywebview;
import android.content.Context;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;
public class Bridge {
Context ctx = null;
public Bridge(Context _ctx){
this.ctx=_ctx;
}
@JavascriptInterface
public void pluginLog(String msg){
Log.i(getClass().getName(),"pluginLog() msg:"+ msg);
Toast.makeText(this.ctx,msg,Toast.LENGTH_SHORT).show();
}
}
<MainActivity.java>
package com.jky.mywebview;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private WebView mWebView = null;
private Button mButton = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true); // 웹뷰의 디버깅 모드 활성화 }
}
this.mWebView = findViewById(R.id.myWebview);
this.mButton = findViewById(R.id.button);
this.mWebView.getSettings().setJavaScriptEnabled(true); // 자바스크립트 사용 허용!!
this.mWebView.addJavascriptInterface(new Bridge(getBaseContext()),"aos"); //window.aos.pluginLog("log test")
this.mWebView.setWebChromeClient(new MyWebChromeClient());
this.mWebView.loadUrl("file:///android_asset/www/sampleWebView.html");
this.mButton.setText("javaScript:webCallback(안녕_Html)");
this.mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Toast.makeText(getBaseContext(),"헐헐",Toast.LENGTH_LONG).show();
mWebView.loadUrl("javaScript:webCallback('안녕_Html');");
}
});
}
}
<MyWebChromeClient.java>
package com.jky.mywebview;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Message;
import android.view.View;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import androidx.annotation.Nullable;
public class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//return super.onJsAlert(view, url, message, result);
new AlertDialog.Builder(view.getContext())
.setTitle("")
.setMessage(message)
.setPositiveButton(android.R.string.ok,
new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setCancelable(false)
.create()
.show();
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
//return super.onJsConfirm(view, url, message, result);
new AlertDialog.Builder(view.getContext())
.setTitle("")
.setMessage(message)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
})
.create()
.show();
return true;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
}
@Override
public void onCloseWindow(WebView window) {
super.onCloseWindow(window);
}
@Nullable
@Override
public View getVideoLoadingProgressView() {
return super.getVideoLoadingProgressView();
}
@Override
public void getVisitedHistory(ValueCallback<String[]> callback) {
super.getVisitedHistory(callback);
}
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}
}
프로젝트 완성 코드:
반응형