最近做的一個項目中,用到自定義地圖,將自定義地圖轉換成html頁面,現在需要做的是如何將本地的html加載到android中,並可以實現交互。
相關講解:
其實webview加載資源的速度並不慢,但是如果資源多了,當然就很慢。圖片、css 、js 、html這些資源每個大概需要10-200ms ,一般都是30ms就ok了。不過webview是必須等到全部資源都完成加載,才會進行渲染的,所以加載的速度很重要!從Google上我們了解到,webview加載頁面的順序是:先加載html,然后從里面解析出css、js文件和頁面上的圖片資源進行加載。如果webkit的緩存里面有,就不加載。加載完這些資源之后,就進行css的渲染和js的執行。CSS的渲染一般不需要很長時間,幾十毫秒就ok。關鍵是js的執行,如果用了jQuery,則執行起來需要5-6秒。而在這段時間,如果不在webview里設置背景,網頁部分是白色的,很難看。這是一個很糟糕的用戶體驗。所以建議如果用網頁布局程序,最好別用那些龐大的js框架。最好使用原生的js寫業務腳本,以提升加載速度,改善用戶體驗。
在Android上怎樣實現JAVA和JS交互呢?
Android的webview是基於webkit內核的,webview中集成了js與java互調的接口函數,通過addJavas criptInterface方法,可以將Java的類注冊進webkit,給網頁上的js進行調用,而且還可以通過loadUrl方法給webkit傳遞一個URL,供瀏覽器來進行解析,實現Java和js交互。
要想運行網頁上的js腳本,webview必須設置支持Javas cript。
Java代碼:1mWebview.getSettings().setJavascriptEnabled(true);
然后是設置webView要加載的網頁:
web的網頁:webView.loadUrl("http://www.google.com");
本地的網頁:webView.loadUrl("file:///android_asset/XX.html"); //本地的存放在:assets文件夾中
webview做完基本的初始化后我們還要要給它,加進一個回調的代理類JavascriptInterface,並給它一個調用的名稱:ncp
Java代碼:1mWebView.addJavas criptInterface(new Javas criptInterface(),"ncp");
Javas criptInterface可以是一個普通的Java類,類實現的方法,均可被js回調:
Java代碼:
final class Javas criptInterface {
public int callOnJs() {
return 1000;
}
public void callOnJs2(String mode) {
//TODO
}
}
Java要調用js的方法,只需知道js的方法名稱即可:
Java代碼:1mWebView.loadUrl("javas cript:onSaveCallback()");
js 這邊就更簡單(存在的版本兼容問題,參考使用WebView過程中的問題總結):
JS代碼:
window.onload = function(){
document.getElementById('btn_1').addEventListener('click', onBtnClick, false);
var _int_value = window.ncp.callOnJs();
alert("get int from java:" + _int_value );
}
function onBtnClick() {
window.ncp.callOnJs2("click");
}
Java和js交互有以下一些特點:
1.Java 調用 js 里面的函數,速度並不令人滿意,大概一次一兩百毫秒吧,如果要做交互性很強的事情,這種速度會讓人瘋掉的。而反過來就不一樣了, js 去調 java 的方法,速度很快,基本上 40-50 毫秒一次。所以盡量用 js 調用 java 方法,而不是 java 去調用 js 函數。
2.Java 調用 js 的函數,沒有返回值,而 Js 調用 java 方法,可以有返回值。返回值可以是基本類型、字符串,也可以是對象。如果是字符串,有個很討厭的問題,第 3 點我會講的。如果是對象,這個對象會被轉換為 js 的對象,直接可以訪問里面的方法。但是我不推薦 java 返回給 js 的是對象,除非是必須。因為 js 收到 java 返回的對象,會產生一些交換對象,而如果這些對象的數量增加到了 500 或 600 以上,程序就會出問題。所以盡量返回基本數據類型或者字符串。
3.Js 調用 Java 的方法,返回值如果是字符串,你會發現這個字符串是 native 的,不能對它進行一些修改操作,比如想對它 substr ,取不到。怎么解決呢?轉成 locale 的。使用 toLocaleString() 函數就可以了。不過這個函數的速度並不快,轉化的字符串如果很多,將會很耗費時間。
下面是一個具體的例子:
1.新建assets文件夾,將本地html頁面拷貝到該文件夾下。
2.xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context=".MainActivity" > <TextView android:id="@+id/tv" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_world" /> <WebView android:layout_below="@+id/tv" android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout>
3.java文件
package com.example.webview_workflowy; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.webkit.WebView; import android.widget.Toast; public class MainActivity extends Activity { private WebView webView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //加載頁面 webView = (WebView) findViewById(R.id.webview); //允許JavaScript執行 webView.getSettings().setJavaScriptEnabled(true); //找到Html文件,也可以用網絡上的文件 webView.loadUrl("file:///android_asset/index.html"); // 添加一個對象, 讓JS可以訪問該對象的方法, 該對象中可以調用JS中的方法 webView.addJavascriptInterface(new Contact(), "contact"); } private final class Contact { //JavaScript調用此方法撥打電話 public void call(String phone) { // startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone))); Toast.makeText(MainActivity.this, phone, Toast.LENGTH_LONG).show(); } //Html調用此方法傳遞數據 public void showcontacts() { String json = "[{\"name\":\"zxx\", \"amount\":\"9999999\", \"phone\":\"18600012345\"}]"; // 調用JS中的方法 webView.loadUrl("javascript:show('" + json + "')"); } public void toast(String str){ Toast.makeText(MainActivity.this, "aaaaaaaaaaaa --- " + str, Toast.LENGTH_LONG).show(); } } }
4.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function show(jsondata){
var jsonobjs = eval(jsondata);
var table = document.getElementById("personTable");
for(var y=0; y<jsonobjs.length; y++){
var tr = table.insertRow(table.rows.length);
var td1 = tr.insertCell(0);
var td2 = tr.insertCell(1);
td2.align = "center";
var td3 = tr.insertCell(2);
td3.align = "center";
td1.innerHTML = jsonobjs[y].name;
td2.innerHTML = jsonobjs[y].amount;
td3.innerHTML = "<a href='javascript:contact.call(\""+ jsonobjs[y].phone+ "\")'>"+ jsonobjs[y].phone+ "</a>";
}
}
</script>
</head>
<body onload="javascript:contact.showcontacts()">
<button id="button" onclick = "javascript:contact.toast('123')">haha</button>
<table border="0" width="100%" id="personTable" cellspacing="0">
<tr>
<td width="30%">姓名</td>
<td width="30%" align="center">存款</td>
<td align="center">電話</td>
</tr>
</table>
</body>
</html>
如果此文對您有幫助,微信打賞我一下吧~

