隨著H5的使用越來越廣泛,逐漸替換App原生的頁面。有的商城類App甚至1/4或1/3都是用網(wǎng)頁做的,所以有的App會有頻繁的與網(wǎng)頁交互。我曾經(jīng)有個做Android的同事,項目經(jīng)理說給一個月的期限不會寫H5就走人,可見H5的重要性了。
效果請看大屏幕:
giphy.gif
如上四個按鈕操作分別為:
- Android調(diào)用Js方法
- Android調(diào)用Js方法并傳參
- Js調(diào)用Android方法
- Js調(diào)用Android方法并傳參
功能實現(xiàn)步驟:
1. 主界面布局
<?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"
tools:context="com.example.androidusejs.MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android模塊"
android:textColor="#000"
android:textStyle="bold"
android:textSize="18sp"/>
<TextView
android:id="@+id/tv_androidcalljs"
android:layout_width="170dp"
android:layout_height="30dp"
android:text="Android調(diào)用Js"
android:background="@drawable/roundsmall_bggreen"
android:gravity="center"
android:layout_marginTop="10dp"
android:textColor="@color/white"/>
<TextView
android:id="@+id/tv_androidcalljsargs"
android:layout_width="170dp"
android:layout_height="30dp"
android:text="Android調(diào)用Js并傳參數(shù)"
android:background="@drawable/roundsmall_bggreen"
android:gravity="center"
android:layout_marginTop="10dp"
android:textColor="@color/white"/>
<TextView
android:id="@+id/tv_showmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="調(diào)用Android顯示結(jié)果"
android:textColor="#000"
android:layout_marginTop="20dp"
android:textSize="20sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
截取預覽圖為:
image.png
2. 在main下創(chuàng)建assets資源文件,并創(chuàng)建html.html文件,項目路徑如下圖:
image.png
3. 給Webview寫最最簡單的html頁面,body里面2個按鈕,javascript里面有2個插入文本的function
<html>
<head>
<meta http-equiv="Content-Type" charset="GB2312"/>
<script type="text/javascript">
function javacalljs(){
document.getElementById("showmsg").innerHTML = "JAVA調(diào)用了JS的無參函數(shù)";
}
function javacalljswith(arg){
document.getElementById("showmsg").innerHTML = (arg);
}
</script>
</head>
<body>
<h3>Web模塊</h3>
<h3 id="showmsg">調(diào)用js顯示結(jié)果</h3>
<input type="button" value="Js調(diào)用Java代碼" onclick="window.android.jsCallAndroid()"/>
<input type="button" value="Js調(diào)用Java代碼并傳參數(shù)" onclick="window.android.jsCallAndroidArgs('Js傳過來的參數(shù)')"/>
</body>
</html>
在瀏覽器中預覽一下:
image.png
image.png
4. 給WebView加入設置:
WebSettings webSettings = webview.getSettings();
//與js交互必須設置
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
webview.addJavascriptInterface(MainActivity.this,"android");
理解:
- webSettings.setJavaScriptEnabled(true) 表示讓WebView支持調(diào)用Js;
- webview.loadUrl("file:///android_asset/html.html") 表示加載assets文件下的html.html文件(因為沒有網(wǎng)絡地址所以加載的本地文件)
- webview.addJavascriptInterface(MainActivity.this,"android") 給webview添加Js調(diào)用接口,第一個參數(shù)為類對象,第二個參數(shù)為自定義別名,Js通過這個別名來調(diào)用Java的方法,我這里自定義為android。
html中用到:<input type="button" value="Js調(diào)用Java代碼" onclick="window.android.jsCallAndroid()"/>
5. Android調(diào)用Js代碼,javacalljs()為javascript代碼中的一個方法。
tvJs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.loadUrl("javascript:javacalljs()");
}
});
如上html中代碼,向id為showmsg的h3大小標題中寫入字符串
function javacalljs(){
document.getElementById("showmsg").innerHTML = "JAVA調(diào)用了JS的無參函數(shù)";
}
同理,Android調(diào)用Js代并傳參數(shù)
webview.loadUrl("javascript:javacalljswith(" + "'Android傳過來的參數(shù)'" + ")");
6. Js調(diào)用Android方法和傳參數(shù)
點擊html按鈕,通過onclick="window.android.jsCallAndroid()事件,通過android別名調(diào)用Java文件的jsCallAndroid()方法。曾經(jīng)Js可直接調(diào)用Java代碼竊取App信息,為安全起見,在Android4.4以上并且必須加入@JavascriptInterface才有響應。
@JavascriptInterface
public void jsCallAndroid(){
tvShowmsg.setText("Js調(diào)用Android方法");
}
@JavascriptInterface
public void jsCallAndroidArgs(String args){
tvShowmsg.setText(args);
}
MainActivity完整代碼:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private WebView webview;
private TextView tvJs;
private TextView tvJsArgs;
private TextView tvShowmsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setWebview();
initView();
}
private void initView() {
tvJs = (TextView) findViewById(R.id.tv_androidcalljs);
tvJsArgs = (TextView) findViewById(R.id.tv_androidcalljsargs);
tvShowmsg = (TextView) findViewById(R.id.tv_showmsg);
tvJs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.loadUrl("javascript:javacalljs()");
}
});
tvJsArgs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webview.loadUrl("javascript:javacalljswith(" + "'Android傳過來的參數(shù)'" + ")");
}
});
}
private void setWebview() {
webview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webview.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportZoom(true);
//與js交互必須設置
webSettings.setJavaScriptEnabled(true);
webview.loadUrl("file:///android_asset/html.html");
webview.addJavascriptInterface(MainActivity.this,"android");
}
@JavascriptInterface
public void jsCallAndroid(){
tvShowmsg.setText("Js調(diào)用Android方法");
}
@JavascriptInterface
public void jsCallAndroidArgs(String args){
tvShowmsg.setText(args);
}
}
打完收工,還不太明白的童鞋可以下載代碼來看并運行測試。