js 與Android交互分為兩種情況:js 調用Android原生方法,Android原生調用 js 方法。
本文將對這兩種情況分別講解,H5 端用 vue
實現。
寫個Android例子:
Android布局文件代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.org.youtu.HtmlActivity"> <Button android:id="@+id/btn_load" android:layout_width="80dp" android:layout_height="wrap_content" android:background="@color/colorPrimaryLight" android:textColor="@color/white_overlay" android:onClick="doClick" android:text="給HTML頁面傳遞數據"/> <WebView android:id="@+id/html_webView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
HTML頁面代碼:
注意:window.callJsFunction = this.callJsFunction 要給原生調用的方法掛載到 window 上面,不然方法無法調用成功,后面不能加括號(),會直接調用此方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>首頁</title> <!-- 引入組件庫 vue.min.js 要在 index.js 之前引入--> <script src="js/vue.min.js"></script> <script src="js/axios.min.js"></script> <!-- 引入樣式 --> <link rel="stylesheet" type="text/css" href="css/index.css"> <!-- 引入組件庫 --> <script src="js/index.js"></script> </head> <body> <div id="appLogin" class="wrap" style="text-align: center;"> <el-button type="success" @click="onSubmit">傳數據到Android后台</el-button> </div> <script type="text/javascript"> var vues = new Vue({ el: '#appLogin', /**-----【數據初始化】-----**/ data() { return { }; }, /**-----【方法啟動執行】-----**/ mounted() { //將要給原生調用的方法掛載到 window 上面 window.callJsFunction = this.callJsFunction }, /**-----【方法列表】-----**/ methods: { onSubmit(){ /**-----【HTML調用Android后台方法】-----**/ window.login.SendDataFromHtml("我是從HTML中傳過來的數據!"); }, callJsFunction(arg) { this.$message.success(arg); }, } }) </script> </body> </html>
邏輯處理Java代碼:
public class HtmlActivity extends AppCompatActivity { private WebView html_webView; @SuppressWarnings("unchecked") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //窗口布局到手機最上方 this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_html); html_webView = this.findViewById(R.id.html_webView); html_webView.getSettings().setJavaScriptEnabled(true); //啟用javascript支持 用於訪問頁面中的javascript html_webView.getSettings().setAllowFileAccess(true); //設置在WebView內部是否允許訪問文件 html_webView.loadUrl("file:///android_asset/login.html"); html_webView.addJavascriptInterface(HtmlActivity.this,"login"); } /**【點擊事件】**/ public void doClick(View view){ switch (view.getId()){ case R.id.btn_load: String arg = "我是Android中定義的字段數據!"; //html_webView.loadUrl("javascript:callJsFunction('我是Android中定義的字段數據!')");//調用HTML中的方法,傳送數據到前端 html_webView.loadUrl("javascript:callJsFunction('" + arg + "')");//調用HTML中的方法,傳送數據到前端 break; } } @android.webkit.JavascriptInterface public void SendDataFromHtml(String data){ Log.e("HTML中傳過來的數據:" , data); Toast.makeText(HtmlActivity.this,data,Toast.LENGTH_LONG).show(); } }
webview的幾種加載方式:
//方式1. 加載一個網頁: webView.loadUrl("http://www.baidu.com/");
//訪問網頁
webView.loadUrl("https://www.baidu.com/");
//系統默認會通過手機瀏覽器打開網頁,為了能夠直接通過WebView顯示網頁,則必須設置
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加載顯示url
view.loadUrl(url);
//返回true
return true;
}
});
//方式2:加載apk包中的html頁面 webView.loadUrl("file:///android_asset/test.html"); //方式3:加載手機本地的html頁面 webView.loadUrl("content://com.android.levi/sdcard/test.html");
webview的Settings常見設置
// webview啟用javascript支持 用於訪問頁面中的javascript settings.setJavaScriptEnabled(true); //設置WebView緩存模式 默認斷網情況下不緩存 settings.setCacheMode(WebSettings.LOAD_DEFAULT); /** * LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據 * LOAD_DEFAULT: (默認)根據cache-control決定是否從網絡上取數據。 * LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據. * LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據。 */ //斷網情況下加載本地緩存 settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);} //讓WebView支持DOM storage API settings.setDomStorageEnabled(true); //讓WebView支持縮放 settings.setSupportZoom(true); //啟用WebView內置縮放功能 settings.setBuiltInZoomControls(true); //讓WebView支持可任意比例縮放 settings.setUseWideViewPort(true); //讓WebView支持播放插件 settings.setPluginState(WebSettings.PluginState.ON); //設置WebView使用內置縮放機制時,是否展現在屏幕縮放控件上 settings.setDisplayZoomControls(false); //設置在WebView內部是否允許訪問文件 settings.setAllowFileAccess(true); //設置WebView的訪問UserAgent settings.setUserAgentString(String string); //設置腳本是否允許自動打開彈窗 settings.setJavaScriptCanOpenWindowsAutomatically(true); // 加快HTML網頁加載完成速度 if (Build.VERSION.SDK_INT >= 19) { settings.setLoadsImagesAutomatically(true); } else { settings.setLoadsImagesAutomatically(false); } // 開啟Application H5 Caches 功能 settings.setAppCacheEnabled(true); // 設置編碼格式 settings.setDefaultTextEncodingName("utf-8");
部分參考:https://www.jianshu.com/p/e8eeec4e8d71
注意事項:html_webView.loadUrl("javascript:callJsFunction('" + arg + "')"); //Android調用HTML中的方法,傳送數據到前端
傳遞的參數 arg ,我在運行試發現一個問題:"( ' " + arg + " ' )",如果在 arg 的兩邊不加 ' 號會報錯:Uncaught SyntaxError: missing
在網上找了一下答案說:js方法傳遞參數時,如果參數是string類型,需要在參數前后加 " "
運行結果: