文章目录

Android提供了一个很强大的WebView控件用来处理Web网页,so, 如何在js来调用android
的方法呢,做个简单的了解记录下。本文主要记录下如何用js调用java中的一些方法,后续会研究
下如何调用java call js的实现,不过个人感觉更多的情况是js 去调用android一些功能

  1. 实验环境as version 17

  2. 首先了解webview中两个重要的概念

  • WebViewClient
    WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:
    onLoadResource,onPageStart,onPageFinish,onReceiveError,onReceivedHttpAuthRequest 等
  • WebChromeClient
    主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等,比如:
    onCloseWindow(关闭WebView),onCreateWindow(),onJsAlert (WebView上alert无效,需要定制WebChromeClient处理弹出),onJsPrompt,onJsConfirm,onProgressChanged,onReceivedIcon,onReceivedTitle 等等
  1. 启动脚本注入,不开启的化,webview中的脚本是无法执行的
  • webView.getSettings().setJavaScriptEnabled(true);
  1. 如何实现webview中的跳转,然后按返回键回到上一个webview,而不是推出app 运行

  2. 遇到的一些问题

    • 注意设置不同版本,17之后版本实现与4.4之前不一样,需要凯inotation
    • 模拟器调试的时候,严格保证html 的书写的规范,不然在as中会报错
  3. 直接上代码,记录下,说不定哪天就用上了呢!有些代码或者布局是无用的

activity_main.xml, 利用主要用到一个组件webview

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<Button
android:layout_width="match_parent"
android:text="testtest"
android:id="@+id/testBtn"
android:layout_height="30dp" />

<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webView"
/>


</RelativeLayout>

webView html- webview_test.html 放到src/main/assets目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>just to test</title>
<style type="text/css">
.red {
color: red;
font-size: 20px;
line-height: 20px;
}

#ua {
color: green;
font-size: 22px;
line-height: 22px;
}

</style>

</head>
<body>

<div class="red">
hello webView ,i just to test
</div>
<code>
....
</code>
------------------
<hr>
<code id="ua"></code>
<button type="button" id="btn">
我是测试按钮
</button>
<button type="button" id="test1">
测试toastMessage按钮
</button>
<a href="http://www.baidu.com">
跳转链接
</a>

<script>
alert('测试一下,但浏览器回退,页面是否重新只系那个');
function jq (id) {
return document.getElementById(id);
}

var btn = jq('btn');
btn.onclick = function () {
alert(111);
}
var btn1 = jq('test1');
/**
* demo 是android 暴露的接口对象的名字
*/


btn1.onclick = function () {
if (window.demo) {

if (window.demo.test) {
jq('ua').innerHTML = window.demo.test;
window.demo.test("sdsfds");
}
else {
alert('not has window.demo.test');
}
}
else {
alert('没有window.demo');
}

}
var uaStr = window.navigator.userAgent;
jq('ua').innerHTML = uaStr;
</script>

</body>
</html>

MainActivity 中实现加载webview并且设置暴露的接口对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.example.zhangshibiao.myapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebChromeClient;
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 {

public WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button btn = (Button)findViewById(R.id.testBtn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "testets", Toast.LENGTH_LONG).show();
}
});



webView = (WebView) findViewById(R.id.webView);
webView.setWebChromeClient(new WebChromeClient());

/**
*
* 如果页面中链接,如果希望点击链接继续在当前browser中响应,
* 而不是新开Android的系统browser中响应该链接,
* 必须覆盖 WebView的WebViewClient对象.
*
* 亲测并没有什么卵用
*/


// webView.setWebViewClient(new WebViewClient());
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url){
view.loadUrl(url);
return true;
}
});

WebSettings settings = webView.getSettings();

/**
* 设置js 生效,如果不设置,webview中的js是不生效的
*/

settings.setJavaScriptEnabled(true);

webView.addJavascriptInterface(new JsInterfaceCla(this), "demo");
webView.loadUrl("file:///android_asset/webview_test.html");
}

/**
* 如果不做任何处理 ,浏览网页,点击系统“Back”键,
* 整个 Browser 会调用 finish()而结束自身,
*
* 如果希望浏览的网页回退而不是推出浏览器,
* 需要在当前Activity中处理并消费掉该 Back 事件
*/


public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}

JsInterfaceCla 主要实现暴露对象,封装相关方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.zhangshibiao.myapp;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

/**
* Created by zhangshibiao on 15/11/15.
*
*
* 这里犯了个错误,之前没有传递context
* 直接使用getApplicationContext 结果调用Toast 的相关方法
* 都没有生效,对android不太熟悉不知道为啥
*/

public class JsInterfaceCla extends AppCompatActivity {
Context mContext;

/** Instantiate the interface and set the context */
JsInterfaceCla(Context c) {
mContext = c;
}

@JavascriptInterface
public void toastMessage() {
Toast.makeText(mContext, "hello js", Toast.LENGTH_LONG).show();
}

@JavascriptInterface
public void test(String message) {
Log.i("jstest", "aaaaaaaaaaaaaaaaaa");
Toast.makeText(mContext, "hello js", Toast.LENGTH_LONG).show();
}
}
文章目录