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