안드로이드

[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);
    }
}

 

프로젝트 완성 코드:

mywebview-20230105.zip
0.11MB

 

하이브리드 웹 기본
반응형