WebView与JavaScript交互--Android
Posted wzjhoutai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebView与JavaScript交互--Android相关的知识,希望对你有一定的参考价值。
转载请注明出处: http://blog.csdn.net/forwardyzk/article/details/46819925
在工作中,有一个这种需求,须要用到WebView与javascript进行交互,以下我们就通过一个简单的需求来介绍.
先看一下效果图:
需求:
1.点击一个button进入一个载入WebView的界面,假设此界面须要分享此界面到其它平台,那么就在当前界面展示"分享"button,假设不须要分享,那么就不展示"分享"button.
2.在H5界面上,有一个登陆button,点击登陆,
2.1 假设没有登陆,则调起登陆界面,登陆成功后,在H5界面展示登陆者.
2.2 假设登陆了,就在H5界面直接显示当前的登陆者.
1.使webview支持js的调用.
webview.addJavascriptInterface(new JsHost(JsActivity.this, mHandler, webview), "jsObject");
当中JsHost是自己定义的一个类, jsObject是H5页面调用clientjs方法的对象(名字也是自己定义的,仅仅要和H5javascriprt用的对象名字一样就可以).
2.分享需求.
当H5页面载入完成后,H5页面调用client是否分享的方法(通过此方法讲是否分享和分享的内容传递给client),然后控制分享button是否展示
H5页面javascrip方法:
window.onload = function share() { //分享 var json = "{‘isShare‘:0,‘shareContent‘:‘我是分享内容‘}"; //不分享 var noShare = "{‘isShare‘:-1}"; window.jsObject.toShare(json); }
这是H5调用client的javascript方法
window:代表当前页面的对象
window.onload表示当前的H5页面载入完成后,调用后面的方法
json:表示须要分享的json字符串
noshare:表示不分享额json字符串
jsObject:是client定义的javascript对象
toShare(json):client的javascript方法,这样在client就能够收到json字符串.(这里传的是须要分享的json字符串)
在client的JsHost中定义javascript的分享方法
/** * 分享的方法 * * @param json */ @JavascriptInterface public void toShare(String json) { Log.d(TAG, "web:" + json); try { JSONObject jsonObject = new JSONObject(json); int isShare = jsonObject.optInt("isShare"); if (isShare == 0) {//表示须要分享 mHandler.sendEmptyMessage(0); } else if (isShare == -1) { //表示不须要分享 mHandler.sendEmptyMessage(1); } } catch (JSONException e) { Log.d(TAG, "解析异常"); } }
首先要添加标识javascript的注解,@JavascriptInerface
解析传递过来的json字符串,通过Handler对象发送消息来控制分享button是否展示
在JsActivity方法中定义了mHandler,通过WebView的设置addJavascriprtInterface方法传递给了JsHost类中
JsActivty相应的不局文件:
activity_js.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_share" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="分享" /> <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/btn_share"></WebView> </RelativeLayout>
private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) {//显示分享 btnShare.setVisibility(View.VISIBLE);//显示分享button } else if (msg.what == 1) {//隐藏分享button btnShare.setVisibility(View.GONE);//隐藏分享button } else if (msg.what == 2) {//调用登录 Intent intent = new Intent(JsActivity.this, LoginActivity.class); startActivityForResult(intent, JsActivity.RESULT_OK); } super.handleMessage(msg); } };
3.1点击登陆,假设没有登陆,弹起登陆界面
先看H5页面点击登陆,调用client的js方法
<input id="loginName" type="button" onclick="isLogin()" value="登录">
function isLogin() { var name = window.jsObject.requestToken(); document.getElementById("loginName").value = name; }
点击"登录",调用了javascript中的isLogin()方法,在isLogin方法中调用client的requestToken()方法.此requestToken()有返回值,返回值是当前登陆者的名字.
client的requestToken方法
/** * 请求登陆者 * * @return */ @JavascriptInterface public String requestToken() { if (TextUtils.isEmpty(App.getName())) { mHandler.sendEmptyMessage(2); } Log.d(TAG, "登陆者名字" + "name=" + App.getName()); return TextUtils.isEmpty(App.getName()) ? "未登录" : App.getName(); }
假设App.getName()获取登陆者的名字,假设为空,则通过mHandelr方法调起登录界面的通知.同一时候将当前登陆者返回给H5页面.
Intent intent = new Intent(JsActivity.this, LoginActivity.class); startActivityForResult(intent, JsActivity.RESULT_OK);
通过startActivityForResult方法开启登陆页面
startActivityForResult的用法请參考:点击
看一下登陆页面:
activity_login.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center_vertical" android:orientation="horizontal"> <TextView android:id="@+id/name_des" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="name:" /> <EditText android:id="@+id/edit_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@id/name_des" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="20dp" android:gravity="center_vertical" android:orientation="horizontal"> <TextView android:id="@+id/pass_des" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="pass:" /> <EditText android:id="@+id/edit_pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@id/pass_des" /> </RelativeLayout> <Button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="Login" /> </LinearLayout>
当点击了loginbutton,运行登陆操作
private void login() { String name = editName.getText().toString().trim(); String pass = editPass.getText().toString().trim(); if (TextUtils.isEmpty(name)) { Toast.makeText(getApplicationContext(), "name is empty", Toast.LENGTH_SHORT).show(); return; } else if (TextUtils.isEmpty(pass)) { Toast.makeText(getApplicationContext(), "pass is empty", Toast.LENGTH_SHORT).show(); return; } else { App.writeLoginInfo(name, pass); setResult(JsActivity.RESULT_OK); finish(); } }
登陆成功后,把name和pass存到了App中
public class App extends Application { private static SharedPreferences sharedPreferences; @Override public void onCreate() { super.onCreate(); sharedPreferences = getApplicationContext().getSharedPreferences("login", Context.MODE_PRIVATE); } public static void writeLoginInfo(String name, String pass) { sharedPreferences.edit().putString("name", name).putString("pass", pass).commit(); } public static String getName() { return sharedPreferences.getString("name", ""); } }
同一时候在JsActivity中的onActivityResult方法中获取到通知,然后调用H5页面的loginSuccess方法,传递给H5client的登录者
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_OK) { String name = App.getName(); name = TextUtils.isEmpty(name) ?"未登录" : name; Log.d(TAG, "onActivityResult:" + "name=" + name); //调用H5的javascript中的loginSuccess方法 webview.loadUrl("javascript:loginSuccess(‘" + name + "‘)"); } }
webview.loadUrl("javascript:loginSuccess(‘"+name+"‘)");
这是client调用H5中的javascript的方法.
function loginSuccess(name) { document.getElementById("loginName").value = name; }
讲name赋给id为loginName控件的value属性.
loginSuccess:是H5中的javascript方法
name:是方法參数
总结:
使用webview的addJavascriprtInterface(操作的对象,"javascript对象名称");
H5调用client方法:
无返回值: window.javascript对象.clientjs方法;
有返回值: var value=window.javascript对象.clientjs方法;
client调用H5的方法:
webview.loadUrl("javascript:方法名称(參数)");
webview.loadUrl("javascript:方法名称()");
到此WebView与javascript方法互相调用已经解说完成,希望对大家有帮助,有不足之处往大家指出.
源代码下载: server和client的源代码
以上是关于WebView与JavaScript交互--Android的主要内容,如果未能解决你的问题,请参考以下文章
android webview与 java与javascript的交互
垃圾收集后来自 Javascript 的 JavaFx WebView 回调失败