1. 程式人生 > >混合開發-webview和原生互動

混合開發-webview和原生互動

混合開發在移動開發中很常見,比如qq中的運動,釐米秀等功能都是用網頁實現的。
混合開發中一個重要的功能就是網頁和原生介面的資料互動,下面將實現一個小demo.

新建一個activity,佈局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.h.learn.WebViewActivity">
<WebView android:layout_weight="1" android:layout_width="match_parent" android:layout_height
="fill_parent" android:id="@+id/my_web_view" />
<LinearLayout android:background="@drawable/webview_bg" android:layout_weight="1" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="fill_parent" >
<EditText android:id="@+id/edit_info" android:text="text" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_confirm" android:text="確定" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/log_text_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> </LinearLayout>

佈局中定義了一個webview,在螢幕上半部分。
底部是原生的一個輸入框和按鈕,輸入框用於輸入資料,按鈕用於呼叫網頁中的介面。
網頁中也應該是類似的,一個輸入框和一個呼叫原生介面的按鈕。
assets資料夾中的網頁程式碼如下:

<!DOCTYPE html>
<html>
<head>
    <title></title>

</head>
<body>
    <script>
        //供原生程式碼呼叫
        function showEditInfo(str){
            alert(str);
        };
        //呼叫原生介面,並把網頁中文字框的內容傳過去
        function callNative()
        {
            var str=document.getElementById("mytext").value;
            window.webview.actionFromJsWithParam(str);
        };
        //alert(1);
        //showEditInfo('123');
    </script>
    <input type="text" value="123" name="mytext" id="mytext">
    <button  onClick="callNative()">呼叫原生介面</button>


</body>
</html>

public class WebViewActivity extends AppCompatActivity {

    @BindView(R.id.my_web_view)WebView webview;
    @BindView(R.id.edit_info)EditText editInfo;
    @BindView(R.id.log_text_view)TextView logTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);

        ButterKnife.bind(this);
        //webview = (WebView) findViewById(R.id.my_web_view);
        Log.d("flag--","onCreate(WebViewActivity.java:20)-->>"+webview);

        initView();
    }

    //呼叫js介面,並把editText中的內容傳到網頁介面中
    @OnClick(R.id.btn_confirm)
    public void confirm(){
        Log.d("flag--","confirm(WebViewActivity.java:35)-->>"+"javascript:showEditInfo('"+editInfo.getText()+"')");
        webview.loadUrl("javascript:showEditInfo('"+editInfo.getText()+"')");
    }

    private void initView() {
        //載入網頁
        webview.loadUrl("file:///android_asset/webview.html");

        //允許彈框
        webview.setWebChromeClient(new WebChromeClient());

        WebSettings webSettings= webview.getSettings();
        //允許執行js
        webSettings.setJavaScriptEnabled(true);
        webview.addJavascriptInterface(this, "webview");
    }

    //供js呼叫的介面
    @android.webkit.JavascriptInterface
    public void actionFromJsWithParam(final String str) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                String text = logTextView.getText() +  "\njs呼叫了Native函式傳遞引數:" + str;
                logTextView.setText(text);
            }
        });

    }

}

webview.addJavascriptInterface(this, “webview”);中第二個引數可以自定義,但要和js中相對應,因此js中呼叫原生介面的方法為 window.webview.actionFromJsWithParam(str);

最終效果:

這裡寫圖片描述

這裡寫圖片描述

常用框架: