Android WebView 开发
2018-03-25 本文已影响77人
that_is_this
1. 遇见问题及解决
- 遇见
chromium: [INFO:CONSOLE(1)] "Uncaught ReferenceError: test is not defined", source: (1)
,这里是调用了 html 的 test 方法,显示的错误信息是 undefined
解决:因为调用 js 里的方法时有两种方法,一种是有返回值,一种是没用返回值,这里是使用了没用返回值的函数调用方式。有两种函数调用的方式:
- 遇见
1. webView.loadUrl("javascript:test()"); // 直接调用
2. String script=String.format("javascript:test()"); // 处理返回值
webView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.i("Wooo", "onReceiverValue : " + s); //返回字符串
}
});
2. JS 与 java 互调
1. js 调 java
在 java 内声明被调函数,并处理逻辑。AAAA 参数是标识字段,在 JS 内会使用到,并作为调用 java 函数的句柄,arg 是 JS 串给 java 的参数
webView.addJavascriptInterface(new JSInterface(), "AAAA");
private class JSInterface {
@JavascriptInterface
public void showToast(String arg){
Toast.makeText(MainActivity.this,arg, Toast.LENGTH_SHORT).show();
}
}
js 调用代码,句柄、函数名要对应上
window.AAAA.showToast('JS中传来的参数');
2. java 调 js
上面说到,有两种调用方式,一个是有参数,一个是无参数返回
//webView.loadUrl("javascript:callJS()"); // 方式一
String script=String.format("javascript:test('i call js')");
webView.evaluateJavascript(script, new ValueCallback<String>() { // 方式二
@Override
public void onReceiveValue(String s) {
Log.i("Wooo", "onReceiverValue : " + s);
}
});
3. 完整代码
- MainActivity
import android.annotation.SuppressLint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
Button b = (Button) findViewById(R.id.bbb);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//webView.loadUrl("javascript:callJS()");
String script=String.format("javascript:test('i call js')");
webView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.i("Wooo", "onReceiverValue : " + s);
}
});
}
});
}
private void init() {
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new myWebViewClient());
WebSettings settings = webView.getSettings();
webView.setWebChromeClient(new myWebChromeClient(MainActivity.this));
settings.setJavaScriptEnabled(true);
settings.setDefaultTextEncodingName("utf-8");
webView.addJavascriptInterface(new JSInterface(), "AAAA");
webView.loadUrl("file:///android_asset/index.html");//http://www.exchen.net/test/index.html file:///android_asset/index.html
}
private class JSInterface {
@JavascriptInterface
public void showToast(String arg){
Toast.makeText(MainActivity.this,arg, Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (webView.canGoBack()) {
webView.goBack();
return true;
} else {
System.exit(0);
}
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
super.onDestroy();
webView.stopLoading();
webView.removeAllViews();
if (webView != null) {
webView.destroy();
webView = null;
}
}
}
- index.xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API</title>
</head>
<body>
<script>
var cpp_object;
if (cpp_object != null){
cpp_object.PageCommunicatesWithTheClient("MSG:HTML to App");
}
function successData(response) {
alert('MSG From App:'+response);
}
function test() {
alert('test');
return "testtt";
}
function callJS(){
alert("Android调用了JS的callJS方法");
return "callJS";
}
function test(var1) {
alert(var1);
window.AAAA.showToast('JS中传来的参数');
return var1;
}
</script>
</body>
</html>
- myWebChromeClient
import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
/**
* Created by Administrator on 2018/3/24.
*/
public class myWebChromeClient extends WebChromeClient {
private ProgressDialog dialog;
private Context mContext;
public myWebChromeClient(Context ctx) {
mContext = ctx;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
closeDialog();
} else {
openDialog(newProgress);
}
}
private void openDialog(int newProgress) {
if (dialog == null) {
dialog = new ProgressDialog(mContext);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setProgress(newProgress);
dialog.setCancelable(true);
dialog.show();
} else {
dialog.setProgress(newProgress);
}
}
private void closeDialog() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.i("Wooo", "title : " + title);
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.i("Wooo", "onJSAlert : " + url + ", message : " + message + ", result : " + result);
return super.onJsAlert(view, url, message, result);
}
}
- myWebViewClient
import android.webkit.WebView;
import android.webkit.WebViewClient;
/**
* Created by Administrator on 2018/3/24.
*/
public class myWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true; //返回值是true的时候是控制网页在WebView中去打开,如果为false调用系统浏览器或第三方浏览器打开
}
}
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
tools:context="cn.saliey.vsoc.MainActivity">
<Button
android:id="@+id/bbb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginRight="20dp"
android:textSize="16sp"
android:text="确定" />
<!--<TextView-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="Hello World!"-->
<!--app:layout_constraintBottom_toBottomOf="parent"-->
<!--app:layout_constraintLeft_toLeftOf="parent"-->
<!--app:layout_constraintRight_toRightOf="parent"-->
<!--app:layout_constraintTop_toTopOf="parent" />-->
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
- 声明权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.vending.BILLING" />